sparkecoder 0.1.44 → 0.1.46

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 (184) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/index.d.ts +2 -2
  3. package/dist/agent/index.js +153 -4
  4. package/dist/agent/index.js.map +1 -1
  5. package/dist/cli.js +209 -22
  6. package/dist/cli.js.map +1 -1
  7. package/dist/db/index.js +11 -3
  8. package/dist/db/index.js.map +1 -1
  9. package/dist/{index-D2eLXP9V.d.ts → index-DJ5qNs1Z.d.ts} +9 -5
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +210 -21
  12. package/dist/index.js.map +1 -1
  13. package/dist/{search-D3Wtf7TJ.d.ts → search-BOYIUmDp.d.ts} +1 -1
  14. package/dist/server/index.js +208 -21
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/tools/index.d.ts +2 -2
  17. package/dist/tools/index.js +11 -3
  18. package/dist/tools/index.js.map +1 -1
  19. package/package.json +1 -1
  20. package/web/.next/BUILD_ID +1 -1
  21. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  22. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  23. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  24. package/web/.next/standalone/web/.next/server/app/(main)/page.js.nft.json +1 -1
  25. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  26. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page.js.nft.json +1 -1
  27. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  29. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  36. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +3 -3
  38. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  39. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  41. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  44. package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +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 +4 -4
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +4 -4
  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 +3 -3
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +2 -2
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +2 -2
  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 +2 -2
  54. package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +4 -4
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +4 -4
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +3 -3
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +2 -2
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +2 -2
  65. package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +4 -4
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +4 -4
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +3 -3
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +2 -2
  72. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +2 -2
  73. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +2 -2
  75. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  76. package/web/.next/standalone/web/.next/server/app/docs.rsc +4 -4
  77. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +4 -4
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +3 -3
  80. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
  81. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
  82. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +2 -2
  83. package/web/.next/standalone/web/.next/server/app/embed/[id]/page.js.nft.json +1 -1
  84. package/web/.next/standalone/web/.next/server/app/embed/[id]/page_client-reference-manifest.js +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  86. package/web/.next/standalone/web/.next/server/app/index.rsc +5 -5
  87. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  88. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  89. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +5 -5
  90. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +3 -3
  92. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  93. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__36edac7c._.js +1 -1
  94. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_85c176b8._.js → 2374f_13da7b2a._.js} +1 -1
  95. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_3eca1553._.js → 2374f_1de2f628._.js} +1 -1
  96. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_8b8baaa3._.js → 2374f_2bfcd3a2._.js} +1 -1
  97. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_0146c9df._.js → 2374f_40c1da73._.js} +1 -1
  98. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_b30bed04._.js → 2374f_41d07cce._.js} +1 -1
  99. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_4d1accac._.js → 2374f_6d8e5e94._.js} +1 -1
  100. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_c99180da._.js → 2374f_88aa1671._.js} +1 -1
  101. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_147b1db0._.js → 2374f_9f2fae06._.js} +1 -1
  102. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_98432ce4._.js → 2374f_ac79ddf4._.js} +1 -1
  103. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_36dd81aa._.js → 2374f_c8f8a326._.js} +1 -1
  104. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_bcffd98c._.js → 2374f_dd21a4e9._.js} +1 -1
  105. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_dde5cdd9._.js → 2374f_e5142825._.js} +1 -1
  106. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_4b3676c4._.js → 2374f_ec658806._.js} +1 -1
  107. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_f5998fca._.js → 2374f_f3c65774._.js} +1 -1
  108. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__43405ad6._.js +3 -0
  109. package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__adf39cf8._.js → [root-of-the-server]__a87e1c27._.js} +6 -4
  110. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__be5e2967._.js +1 -1
  111. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__de76483d._.js +1 -1
  112. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_76f53fe7._.js → web_273500a6._.js} +2 -2
  113. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_76ccf09f._.js → web_2b3a5919._.js} +2 -2
  114. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_633d8a33._.js → web_329773d1._.js} +2 -2
  115. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_248fc1f2._.js → web_38156da8._.js} +2 -2
  116. package/web/.next/standalone/web/.next/server/chunks/ssr/web_8305f089._.js +7 -0
  117. package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_app_(main)_page_tsx_5ac4794b._.js +1 -1
  118. package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_components_sessions-sidebar_tsx_92510070._.js +1 -1
  119. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  120. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  121. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  122. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  123. package/web/.next/standalone/web/.next/static/{static/chunks/194b3ed8e8d9c0e9.js → chunks/294ebe8457006bce.js} +3 -3
  124. package/web/.next/standalone/web/.next/static/chunks/{23aa98f6e3d7e0e4.js → 7e48d04fbd6dd7a6.js} +5 -3
  125. package/web/.next/standalone/web/.next/static/{static/chunks/1e9fdac31c7fd474.js → chunks/81685e5e8be4eac9.js} +3 -3
  126. package/web/.next/{static/chunks/3425251cd978da61.js → standalone/web/.next/static/chunks/8d3efc76109d2efc.js} +1 -1
  127. package/web/.next/standalone/web/.next/static/chunks/96ec96279ada0efe.js +1 -0
  128. package/web/.next/standalone/web/.next/static/chunks/b31b0765abe0c427.js +1 -0
  129. package/web/.next/standalone/web/.next/static/{static/chunks/c06faa5848e3b0b3.js → chunks/b7d722dab2a7ecc0.js} +1 -1
  130. package/web/.next/standalone/web/.next/static/chunks/cc6d43f798bbe415.js +5 -0
  131. package/web/.next/standalone/web/.next/static/chunks/de300ff10b63be85.css +1 -0
  132. package/web/.next/standalone/web/.next/static/chunks/de71e63276f488bb.js +7 -0
  133. package/web/.next/standalone/web/.next/static/{chunks/194b3ed8e8d9c0e9.js → static/chunks/294ebe8457006bce.js} +3 -3
  134. package/web/.next/standalone/web/.next/static/static/chunks/{23aa98f6e3d7e0e4.js → 7e48d04fbd6dd7a6.js} +5 -3
  135. package/web/.next/{static/chunks/1e9fdac31c7fd474.js → standalone/web/.next/static/static/chunks/81685e5e8be4eac9.js} +3 -3
  136. package/web/.next/standalone/web/.next/static/{chunks/3425251cd978da61.js → static/chunks/8d3efc76109d2efc.js} +1 -1
  137. package/web/.next/standalone/web/.next/static/static/chunks/96ec96279ada0efe.js +1 -0
  138. package/web/.next/standalone/web/.next/static/static/chunks/b31b0765abe0c427.js +1 -0
  139. package/web/.next/{static/chunks/c06faa5848e3b0b3.js → standalone/web/.next/static/static/chunks/b7d722dab2a7ecc0.js} +1 -1
  140. package/web/.next/standalone/web/.next/static/static/chunks/cc6d43f798bbe415.js +5 -0
  141. package/web/.next/standalone/web/.next/static/static/chunks/de300ff10b63be85.css +1 -0
  142. package/web/.next/standalone/web/.next/static/static/chunks/de71e63276f488bb.js +7 -0
  143. package/web/.next/standalone/web/src/app/(main)/page.tsx +2 -2
  144. package/web/.next/standalone/web/src/app/api/config/route.ts +3 -2
  145. package/web/.next/standalone/web/src/components/chat-interface.tsx +324 -37
  146. package/web/.next/standalone/web/src/components/sessions-sidebar.tsx +1 -1
  147. package/web/.next/standalone/web/src/lib/api.ts +3 -0
  148. package/web/.next/standalone/web/src/lib/config.ts +2 -1
  149. package/web/.next/static/chunks/{194b3ed8e8d9c0e9.js → 294ebe8457006bce.js} +3 -3
  150. package/web/.next/static/chunks/{23aa98f6e3d7e0e4.js → 7e48d04fbd6dd7a6.js} +5 -3
  151. package/web/.next/{standalone/web/.next/static/chunks/1e9fdac31c7fd474.js → static/chunks/81685e5e8be4eac9.js} +3 -3
  152. package/web/.next/{standalone/web/.next/static/static/chunks/3425251cd978da61.js → static/chunks/8d3efc76109d2efc.js} +1 -1
  153. package/web/.next/static/chunks/96ec96279ada0efe.js +1 -0
  154. package/web/.next/static/chunks/b31b0765abe0c427.js +1 -0
  155. package/web/.next/{standalone/web/.next/static/chunks/c06faa5848e3b0b3.js → static/chunks/b7d722dab2a7ecc0.js} +1 -1
  156. package/web/.next/static/chunks/cc6d43f798bbe415.js +5 -0
  157. package/web/.next/static/chunks/de300ff10b63be85.css +1 -0
  158. package/web/.next/static/chunks/de71e63276f488bb.js +7 -0
  159. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__9d3fe3b4._.js +0 -3
  160. package/web/.next/standalone/web/.next/server/chunks/ssr/web_631133e0._.js +0 -7
  161. package/web/.next/standalone/web/.next/static/chunks/2110d26bc24ed542.js +0 -1
  162. package/web/.next/standalone/web/.next/static/chunks/4fe97b7866eacdcf.js +0 -7
  163. package/web/.next/standalone/web/.next/static/chunks/7c000de1a1357775.css +0 -1
  164. package/web/.next/standalone/web/.next/static/chunks/a895d50f76a48e6e.js +0 -1
  165. package/web/.next/standalone/web/.next/static/chunks/dccaa0e6b27241a5.js +0 -5
  166. package/web/.next/standalone/web/.next/static/static/chunks/2110d26bc24ed542.js +0 -1
  167. package/web/.next/standalone/web/.next/static/static/chunks/4fe97b7866eacdcf.js +0 -7
  168. package/web/.next/standalone/web/.next/static/static/chunks/7c000de1a1357775.css +0 -1
  169. package/web/.next/standalone/web/.next/static/static/chunks/a895d50f76a48e6e.js +0 -1
  170. package/web/.next/standalone/web/.next/static/static/chunks/dccaa0e6b27241a5.js +0 -5
  171. package/web/.next/static/chunks/2110d26bc24ed542.js +0 -1
  172. package/web/.next/static/chunks/4fe97b7866eacdcf.js +0 -7
  173. package/web/.next/static/chunks/7c000de1a1357775.css +0 -1
  174. package/web/.next/static/chunks/a895d50f76a48e6e.js +0 -1
  175. package/web/.next/static/chunks/dccaa0e6b27241a5.js +0 -5
  176. /package/web/.next/standalone/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_buildManifest.js +0 -0
  177. /package/web/.next/standalone/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_clientMiddlewareManifest.json +0 -0
  178. /package/web/.next/standalone/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_ssgManifest.js +0 -0
  179. /package/web/.next/standalone/web/.next/static/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_buildManifest.js +0 -0
  180. /package/web/.next/standalone/web/.next/static/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_clientMiddlewareManifest.json +0 -0
  181. /package/web/.next/standalone/web/.next/static/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_ssgManifest.js +0 -0
  182. /package/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_buildManifest.js +0 -0
  183. /package/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_clientMiddlewareManifest.json +0 -0
  184. /package/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -84,7 +84,7 @@ var init_types = __esm({
84
84
  }).optional();
85
85
  SparkcoderConfigSchema = z.object({
86
86
  // Default model to use (Vercel AI Gateway format)
87
- defaultModel: z.string().default("anthropic/claude-opus-4-5"),
87
+ defaultModel: z.string().default("anthropic/claude-opus-4-6"),
88
88
  // Working directory for file operations
89
89
  workingDirectory: z.string().optional(),
90
90
  // Tool approval settings
@@ -486,12 +486,16 @@ function closeRemoteDatabase() {
486
486
  authKey = null;
487
487
  }
488
488
  var DATE_FIELDS = ["createdAt", "updatedAt", "startedAt", "completedAt", "stoppedAt", "finishedAt", "loadedAt", "indexedAt", "lastFullIndex", "lastIncrementalIndex"];
489
+ var MODEL_MESSAGE_FIELDS = ["modelMessage", "modelMessages"];
489
490
  function parseDates(obj) {
490
491
  if (obj === null || obj === void 0) return obj;
491
492
  if (Array.isArray(obj)) return obj.map(parseDates);
492
- if (typeof obj !== "object") return obj;
493
+ if (typeof obj !== "object" || obj instanceof Date) return obj;
493
494
  const result = { ...obj };
494
495
  for (const key of Object.keys(result)) {
496
+ if (MODEL_MESSAGE_FIELDS.includes(key)) {
497
+ continue;
498
+ }
495
499
  if (DATE_FIELDS.includes(key) && typeof result[key] === "string") {
496
500
  result[key] = new Date(result[key]);
497
501
  } else if (typeof result[key] === "object") {
@@ -524,7 +528,11 @@ async function api(path, options = {}) {
524
528
  if (!text || text === "null") {
525
529
  return null;
526
530
  }
527
- return parseDates(JSON.parse(text));
531
+ const parsed = JSON.parse(text);
532
+ if (options.skipParseDates) {
533
+ return parsed;
534
+ }
535
+ return parseDates(parsed);
528
536
  }
529
537
  var remoteSessionQueries = {
530
538
  create(data) {
@@ -564,7 +572,7 @@ var remoteMessageQueries = {
564
572
  return api(`/messages/session/${sessionId}`);
565
573
  },
566
574
  getModelMessages(sessionId) {
567
- return api(`/messages/session/${sessionId}/model-messages`);
575
+ return api(`/messages/session/${sessionId}/model-messages`, { skipParseDates: true });
568
576
  },
569
577
  async getRecentBySession(sessionId, limit = 50) {
570
578
  const messages = await api(`/messages/session/${sessionId}`);
@@ -4461,6 +4469,142 @@ ${conversationHistory}
4461
4469
  Summary:`;
4462
4470
  }
4463
4471
 
4472
+ // src/utils/sanitize-messages.ts
4473
+ import { modelMessageSchema } from "ai";
4474
+ function convertDatesToStrings(value) {
4475
+ if (value === null || value === void 0) return value;
4476
+ if (value instanceof Date) return value.toISOString();
4477
+ if (Array.isArray(value)) return value.map(convertDatesToStrings);
4478
+ if (typeof value === "object") {
4479
+ const result = {};
4480
+ for (const [k, v] of Object.entries(value)) {
4481
+ result[k] = convertDatesToStrings(v);
4482
+ }
4483
+ return result;
4484
+ }
4485
+ return value;
4486
+ }
4487
+ function sanitizeMessage(msg) {
4488
+ if (msg === null || msg === void 0 || typeof msg !== "object") return msg;
4489
+ const message = msg;
4490
+ if (!message.role || typeof message.role !== "string") return msg;
4491
+ return convertDatesToStrings(message);
4492
+ }
4493
+ function mergeUserContent(a, b) {
4494
+ const aIsString = typeof a === "string";
4495
+ const bIsString = typeof b === "string";
4496
+ if (aIsString && bIsString) {
4497
+ return `${a}
4498
+
4499
+ ${b}`;
4500
+ }
4501
+ const aParts = aIsString ? [{ type: "text", text: a }] : Array.isArray(a) ? a : [];
4502
+ const bParts = bIsString ? [{ type: "text", text: b }] : Array.isArray(b) ? b : [];
4503
+ return [...aParts, ...bParts];
4504
+ }
4505
+ function mergeConsecutiveSameRole(messages) {
4506
+ if (messages.length <= 1) return messages;
4507
+ const merged = [];
4508
+ for (const msg of messages) {
4509
+ const prev = merged[merged.length - 1];
4510
+ if (!prev || prev.role !== msg.role) {
4511
+ merged.push(msg);
4512
+ continue;
4513
+ }
4514
+ const role = msg.role;
4515
+ if (role === "user") {
4516
+ const mergedContent = mergeUserContent(prev.content, msg.content);
4517
+ merged[merged.length - 1] = { role: "user", content: mergedContent };
4518
+ console.warn("[sanitize-messages] Merged consecutive user messages");
4519
+ } else if (role === "assistant") {
4520
+ const prevParts = typeof prev.content === "string" ? [{ type: "text", text: prev.content }] : Array.isArray(prev.content) ? prev.content : [];
4521
+ const curParts = typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : Array.isArray(msg.content) ? msg.content : [];
4522
+ merged[merged.length - 1] = { role: "assistant", content: [...prevParts, ...curParts] };
4523
+ console.warn("[sanitize-messages] Merged consecutive assistant messages");
4524
+ } else if (role === "tool") {
4525
+ const prevContent = Array.isArray(prev.content) ? prev.content : [];
4526
+ const curContent = Array.isArray(msg.content) ? msg.content : [];
4527
+ merged[merged.length - 1] = { role: "tool", content: [...prevContent, ...curContent] };
4528
+ console.warn("[sanitize-messages] Merged consecutive tool messages");
4529
+ } else {
4530
+ merged.push(msg);
4531
+ }
4532
+ }
4533
+ return merged;
4534
+ }
4535
+ function sanitizeModelMessages(messages) {
4536
+ let allValid = true;
4537
+ for (const msg of messages) {
4538
+ try {
4539
+ modelMessageSchema.parse(msg);
4540
+ } catch {
4541
+ allValid = false;
4542
+ break;
4543
+ }
4544
+ }
4545
+ let result;
4546
+ if (allValid) {
4547
+ result = messages;
4548
+ } else {
4549
+ console.warn("[sanitize-messages] Detected invalid messages, attempting self-repair...");
4550
+ const sanitized = [];
4551
+ let repairCount = 0;
4552
+ for (let i = 0; i < messages.length; i++) {
4553
+ const msg = messages[i];
4554
+ try {
4555
+ modelMessageSchema.parse(msg);
4556
+ sanitized.push(msg);
4557
+ continue;
4558
+ } catch {
4559
+ }
4560
+ const fixed = sanitizeMessage(msg);
4561
+ try {
4562
+ modelMessageSchema.parse(fixed);
4563
+ sanitized.push(fixed);
4564
+ repairCount++;
4565
+ console.warn(`[sanitize-messages] Repaired message ${i} (role=${msg.role}) - converted Date objects to strings`);
4566
+ continue;
4567
+ } catch {
4568
+ }
4569
+ if (msg.role === "tool" && Array.isArray(msg.content)) {
4570
+ const fixedContent = msg.content.map((part) => {
4571
+ if (part.type === "tool-result" && part.output !== void 0) {
4572
+ const output = convertDatesToStrings(part.output);
4573
+ if (output && typeof output === "object" && !output.type) {
4574
+ return { ...part, output: { type: "json", value: output } };
4575
+ }
4576
+ const knownTypes = ["text", "json", "execution-denied", "error-text", "error-json", "content"];
4577
+ if (output && typeof output === "object" && !knownTypes.includes(output.type)) {
4578
+ return { ...part, output: { type: "json", value: output } };
4579
+ }
4580
+ return { ...part, output };
4581
+ }
4582
+ return convertDatesToStrings(part);
4583
+ });
4584
+ const wrappedMsg = { ...msg, content: fixedContent };
4585
+ try {
4586
+ modelMessageSchema.parse(wrappedMsg);
4587
+ sanitized.push(wrappedMsg);
4588
+ repairCount++;
4589
+ console.warn(`[sanitize-messages] Repaired message ${i} (role=tool) - wrapped raw output in json type`);
4590
+ continue;
4591
+ } catch {
4592
+ }
4593
+ }
4594
+ console.error(
4595
+ `[sanitize-messages] Could not repair message ${i} (role=${msg.role}). Message will be included as-is. Content keys: ${JSON.stringify(Object.keys(msg))}`
4596
+ );
4597
+ sanitized.push(msg);
4598
+ }
4599
+ if (repairCount > 0) {
4600
+ console.warn(`[sanitize-messages] Self-repair complete: fixed ${repairCount}/${messages.length} messages`);
4601
+ }
4602
+ result = sanitized;
4603
+ }
4604
+ result = mergeConsecutiveSameRole(result);
4605
+ return result;
4606
+ }
4607
+
4464
4608
  // src/agent/context.ts
4465
4609
  var ContextManager = class {
4466
4610
  sessionId;
@@ -4477,9 +4621,14 @@ var ContextManager = class {
4477
4621
  /**
4478
4622
  * Get messages for the current context
4479
4623
  * Returns ModelMessage[] that can be passed directly to streamText/generateText
4624
+ *
4625
+ * Includes self-repair: if messages from the database have been corrupted
4626
+ * (e.g., Date objects in tool outputs from parseDates), they are automatically
4627
+ * sanitized to conform to the AI SDK's ModelMessage schema.
4480
4628
  */
4481
4629
  async getMessages() {
4482
4630
  let modelMessages = await messageQueries.getModelMessages(this.sessionId);
4631
+ modelMessages = sanitizeModelMessages(modelMessages);
4483
4632
  const contextSize = calculateContextSize(modelMessages);
4484
4633
  if (this.autoSummarize && contextSize > this.maxContextChars) {
4485
4634
  modelMessages = await this.summarizeContext(modelMessages);
@@ -4926,9 +5075,28 @@ import { existsSync as existsSync12, mkdirSync as mkdirSync3, writeFileSync as w
4926
5075
  import { readdir as readdir4 } from "fs/promises";
4927
5076
  import { join as join6, basename as basename3, extname as extname7, relative as relative8 } from "path";
4928
5077
  import { nanoid as nanoid4 } from "nanoid";
5078
+
5079
+ // src/server/devtools-store.ts
5080
+ var devtoolsContextStore = /* @__PURE__ */ new Map();
5081
+ function setDevtoolsContext(sessionId, context) {
5082
+ devtoolsContextStore.set(sessionId, context);
5083
+ }
5084
+ function getDevtoolsContext(sessionId) {
5085
+ cleanupStaleContexts();
5086
+ return devtoolsContextStore.get(sessionId) || null;
5087
+ }
5088
+ function cleanupStaleContexts() {
5089
+ const now = Date.now();
5090
+ for (const [sessionId, ctx] of devtoolsContextStore) {
5091
+ if (now - ctx.lastHeartbeat.getTime() > 30 * 1e3) {
5092
+ devtoolsContextStore.delete(sessionId);
5093
+ }
5094
+ }
5095
+ }
5096
+
5097
+ // src/server/routes/sessions.ts
4929
5098
  var sessions = new Hono();
4930
5099
  var pendingInputStore = /* @__PURE__ */ new Map();
4931
- var devtoolsContextStore = /* @__PURE__ */ new Map();
4932
5100
  function cleanupPendingInputs() {
4933
5101
  const now = Date.now();
4934
5102
  for (const [sessionId, entry] of pendingInputStore) {
@@ -4937,14 +5105,6 @@ function cleanupPendingInputs() {
4937
5105
  }
4938
5106
  }
4939
5107
  }
4940
- function cleanupDevtoolsContexts() {
4941
- const now = Date.now();
4942
- for (const [sessionId, ctx] of devtoolsContextStore) {
4943
- if (now - ctx.lastHeartbeat.getTime() > 30 * 1e3) {
4944
- devtoolsContextStore.delete(sessionId);
4945
- }
4946
- }
4947
- }
4948
5108
  var createSessionSchema = z12.object({
4949
5109
  name: z12.string().optional(),
4950
5110
  workingDirectory: z12.string().optional(),
@@ -5203,7 +5363,10 @@ sessions.get("/:id/pending-input", async (c) => {
5203
5363
  var devtoolsContextSchema = z12.object({
5204
5364
  url: z12.string(),
5205
5365
  path: z12.string(),
5206
- pageName: z12.string().optional()
5366
+ pageName: z12.string().optional(),
5367
+ screenWidth: z12.number().optional(),
5368
+ screenHeight: z12.number().optional(),
5369
+ devicePixelRatio: z12.number().optional()
5207
5370
  });
5208
5371
  sessions.post(
5209
5372
  "/:id/devtools-context",
@@ -5211,20 +5374,21 @@ sessions.post(
5211
5374
  async (c) => {
5212
5375
  const id = c.req.param("id");
5213
5376
  const body = c.req.valid("json");
5214
- devtoolsContextStore.set(id, {
5377
+ setDevtoolsContext(id, {
5215
5378
  url: body.url,
5216
5379
  path: body.path,
5217
5380
  pageName: body.pageName || body.path,
5381
+ screenWidth: body.screenWidth,
5382
+ screenHeight: body.screenHeight,
5383
+ devicePixelRatio: body.devicePixelRatio,
5218
5384
  lastHeartbeat: /* @__PURE__ */ new Date()
5219
5385
  });
5220
- cleanupDevtoolsContexts();
5221
5386
  return c.json({ success: true, sessionId: id });
5222
5387
  }
5223
5388
  );
5224
5389
  sessions.get("/:id/devtools-context", async (c) => {
5225
5390
  const id = c.req.param("id");
5226
- cleanupDevtoolsContexts();
5227
- const ctx = devtoolsContextStore.get(id);
5391
+ const ctx = getDevtoolsContext(id);
5228
5392
  if (!ctx) {
5229
5393
  return c.json({ connected: false, context: null });
5230
5394
  }
@@ -5234,6 +5398,9 @@ sessions.get("/:id/devtools-context", async (c) => {
5234
5398
  url: ctx.url,
5235
5399
  path: ctx.path,
5236
5400
  pageName: ctx.pageName,
5401
+ screenWidth: ctx.screenWidth,
5402
+ screenHeight: ctx.screenHeight,
5403
+ devicePixelRatio: ctx.devicePixelRatio,
5237
5404
  lastHeartbeat: ctx.lastHeartbeat.toISOString()
5238
5405
  }
5239
5406
  });
@@ -5814,6 +5981,25 @@ async function emitSyntheticToolStreaming(writeSSE, toolCallStarts, toolCallId,
5814
5981
  await new Promise((resolve10) => setTimeout(resolve10, 0));
5815
5982
  }
5816
5983
  }
5984
+ function buildDevtoolsContextXml(sessionId) {
5985
+ const ctx = getDevtoolsContext(sessionId);
5986
+ if (!ctx) return "";
5987
+ const parts = [];
5988
+ parts.push(`<devtools-context>`);
5989
+ parts.push(` <page url="${ctx.url}" path="${ctx.path}" name="${ctx.pageName}" />`);
5990
+ if (ctx.screenWidth && ctx.screenHeight) {
5991
+ parts.push(` <viewport width="${ctx.screenWidth}" height="${ctx.screenHeight}"${ctx.devicePixelRatio ? ` dpr="${ctx.devicePixelRatio}"` : ""} />`);
5992
+ }
5993
+ parts.push(`</devtools-context>`);
5994
+ return parts.join("\n");
5995
+ }
5996
+ function enrichPromptWithDevtoolsContext(sessionId, prompt) {
5997
+ const xml = buildDevtoolsContextXml(sessionId);
5998
+ if (!xml) return prompt;
5999
+ return `${xml}
6000
+
6001
+ ${prompt}`;
6002
+ }
5817
6003
  var agents = new Hono2();
5818
6004
  var attachmentSchema = z13.object({
5819
6005
  type: z13.enum(["image", "file"]),
@@ -6149,7 +6335,8 @@ agents.post(
6149
6335
  zValidator2("json", runPromptSchema),
6150
6336
  async (c) => {
6151
6337
  const id = c.req.param("id");
6152
- const { prompt, attachments } = c.req.valid("json");
6338
+ const { prompt: rawPrompt, attachments } = c.req.valid("json");
6339
+ const prompt = enrichPromptWithDevtoolsContext(id, rawPrompt);
6153
6340
  const session = await sessionQueries.getById(id);
6154
6341
  if (!session) {
6155
6342
  return c.json({ error: "Session not found" }, 404);
@@ -6294,7 +6481,8 @@ agents.post(
6294
6481
  zValidator2("json", runPromptSchema),
6295
6482
  async (c) => {
6296
6483
  const id = c.req.param("id");
6297
- const { prompt } = c.req.valid("json");
6484
+ const { prompt: rawPrompt } = c.req.valid("json");
6485
+ const prompt = enrichPromptWithDevtoolsContext(id, rawPrompt);
6298
6486
  const session = await sessionQueries.getById(id);
6299
6487
  if (!session) {
6300
6488
  return c.json({ error: "Session not found" }, 404);
@@ -6409,6 +6597,7 @@ agents.post(
6409
6597
  sessionConfig: body.toolApprovals ? { toolApprovals: body.toolApprovals } : void 0
6410
6598
  });
6411
6599
  const session = agent.getSession();
6600
+ const enrichedPrompt = enrichPromptWithDevtoolsContext(session.id, body.prompt);
6412
6601
  const streamId = `stream_${session.id}_${nanoid5(10)}`;
6413
6602
  await createCheckpoint(session.id, session.workingDirectory, 0);
6414
6603
  await activeStreamQueries.create(session.id, streamId);
@@ -6458,7 +6647,7 @@ agents.post(
6458
6647
  let textId = `text_${Date.now()}`;
6459
6648
  let textStarted = false;
6460
6649
  const result = await agent.stream({
6461
- prompt: body.prompt,
6650
+ prompt: enrichedPrompt,
6462
6651
  abortSignal: abortController.signal,
6463
6652
  // Use our managed abort controller, NOT client signal
6464
6653
  onToolProgress: async (progress) => {