@mariozechner/pi-web-ui 0.5.44 → 0.5.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 (346) hide show
  1. package/README.md +178 -99
  2. package/dist/ChatPanel.d.ts +15 -10
  3. package/dist/ChatPanel.d.ts.map +1 -1
  4. package/dist/ChatPanel.js +68 -100
  5. package/dist/ChatPanel.js.map +1 -1
  6. package/dist/{state/agent-session.d.ts → agent/agent.d.ts} +23 -19
  7. package/dist/agent/agent.d.ts.map +1 -0
  8. package/dist/{state/agent-session.js → agent/agent.js} +50 -32
  9. package/dist/agent/agent.js.map +1 -0
  10. package/dist/{state → agent}/transports/AppTransport.d.ts +1 -3
  11. package/dist/agent/transports/AppTransport.d.ts.map +1 -0
  12. package/dist/{state → agent}/transports/AppTransport.js +5 -4
  13. package/dist/{state → agent}/transports/AppTransport.js.map +1 -1
  14. package/dist/{state → agent}/transports/ProviderTransport.d.ts +1 -3
  15. package/dist/agent/transports/ProviderTransport.d.ts.map +1 -0
  16. package/dist/{state → agent}/transports/ProviderTransport.js +6 -7
  17. package/dist/agent/transports/ProviderTransport.js.map +1 -0
  18. package/dist/{state → agent}/transports/index.d.ts.map +1 -1
  19. package/dist/agent/transports/index.js.map +1 -0
  20. package/dist/{state → agent}/transports/proxy-types.d.ts.map +1 -1
  21. package/dist/agent/transports/proxy-types.js.map +1 -0
  22. package/dist/agent/transports/types.d.ts +12 -0
  23. package/dist/agent/transports/types.d.ts.map +1 -0
  24. package/dist/{state → agent}/transports/types.js.map +1 -1
  25. package/dist/{state → agent}/types.d.ts.map +1 -1
  26. package/dist/{state → agent}/types.js.map +1 -1
  27. package/dist/app.css +1 -1
  28. package/dist/components/AgentInterface.d.ts +7 -4
  29. package/dist/components/AgentInterface.d.ts.map +1 -1
  30. package/dist/components/AgentInterface.js +29 -17
  31. package/dist/components/AgentInterface.js.map +1 -1
  32. package/dist/components/ConsoleBlock.d.ts +1 -0
  33. package/dist/components/ConsoleBlock.d.ts.map +1 -1
  34. package/dist/components/ConsoleBlock.js +7 -1
  35. package/dist/components/ConsoleBlock.js.map +1 -1
  36. package/dist/components/ExpandableSection.d.ts +15 -0
  37. package/dist/components/ExpandableSection.d.ts.map +1 -0
  38. package/dist/components/ExpandableSection.js +63 -0
  39. package/dist/components/ExpandableSection.js.map +1 -0
  40. package/dist/components/MessageEditor.d.ts +8 -1
  41. package/dist/components/MessageEditor.d.ts.map +1 -1
  42. package/dist/components/MessageEditor.js +149 -6
  43. package/dist/components/MessageEditor.js.map +1 -1
  44. package/dist/components/MessageList.d.ts +3 -2
  45. package/dist/components/MessageList.d.ts.map +1 -1
  46. package/dist/components/MessageList.js +14 -1
  47. package/dist/components/MessageList.js.map +1 -1
  48. package/dist/components/Messages.d.ts +15 -6
  49. package/dist/components/Messages.d.ts.map +1 -1
  50. package/dist/components/Messages.js +17 -83
  51. package/dist/components/Messages.js.map +1 -1
  52. package/dist/components/ProviderKeyInput.d.ts.map +1 -1
  53. package/dist/components/ProviderKeyInput.js +6 -5
  54. package/dist/components/ProviderKeyInput.js.map +1 -1
  55. package/dist/components/SandboxedIframe.d.ts +29 -7
  56. package/dist/components/SandboxedIframe.d.ts.map +1 -1
  57. package/dist/components/SandboxedIframe.js +350 -282
  58. package/dist/components/SandboxedIframe.js.map +1 -1
  59. package/dist/components/message-renderer-registry.d.ts +12 -0
  60. package/dist/components/message-renderer-registry.d.ts.map +1 -0
  61. package/dist/components/message-renderer-registry.js +12 -0
  62. package/dist/components/message-renderer-registry.js.map +1 -0
  63. package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts +35 -0
  64. package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -0
  65. package/dist/components/sandbox/ArtifactsRuntimeProvider.js +189 -0
  66. package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -0
  67. package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts +17 -0
  68. package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -0
  69. package/dist/components/sandbox/AttachmentsRuntimeProvider.js +64 -0
  70. package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -0
  71. package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts +42 -0
  72. package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -0
  73. package/dist/components/sandbox/ConsoleRuntimeProvider.js +161 -0
  74. package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -0
  75. package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts +30 -0
  76. package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -0
  77. package/dist/components/sandbox/FileDownloadRuntimeProvider.js +97 -0
  78. package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -0
  79. package/dist/components/sandbox/RuntimeMessageBridge.d.ts +19 -0
  80. package/dist/components/sandbox/RuntimeMessageBridge.d.ts.map +1 -0
  81. package/dist/components/sandbox/RuntimeMessageBridge.js +74 -0
  82. package/dist/components/sandbox/RuntimeMessageBridge.js.map +1 -0
  83. package/dist/components/sandbox/RuntimeMessageRouter.d.ts +65 -0
  84. package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -0
  85. package/dist/components/sandbox/RuntimeMessageRouter.js +168 -0
  86. package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -0
  87. package/dist/components/sandbox/SandboxRuntimeProvider.d.ts +33 -0
  88. package/dist/components/sandbox/SandboxRuntimeProvider.d.ts.map +1 -0
  89. package/dist/components/sandbox/SandboxRuntimeProvider.js +2 -0
  90. package/dist/components/sandbox/SandboxRuntimeProvider.js.map +1 -0
  91. package/dist/dialogs/ApiKeyPromptDialog.d.ts.map +1 -1
  92. package/dist/dialogs/ApiKeyPromptDialog.js +2 -5
  93. package/dist/dialogs/ApiKeyPromptDialog.js.map +1 -1
  94. package/dist/dialogs/ModelSelector.js.map +1 -1
  95. package/dist/dialogs/PersistentStorageDialog.d.ts +17 -0
  96. package/dist/dialogs/PersistentStorageDialog.d.ts.map +1 -0
  97. package/dist/dialogs/PersistentStorageDialog.js +144 -0
  98. package/dist/dialogs/PersistentStorageDialog.js.map +1 -0
  99. package/dist/dialogs/SessionListDialog.d.ts +19 -0
  100. package/dist/dialogs/SessionListDialog.d.ts.map +1 -0
  101. package/dist/dialogs/SessionListDialog.js +152 -0
  102. package/dist/dialogs/SessionListDialog.js.map +1 -0
  103. package/dist/dialogs/SettingsDialog.d.ts.map +1 -1
  104. package/dist/dialogs/SettingsDialog.js +1 -0
  105. package/dist/dialogs/SettingsDialog.js.map +1 -1
  106. package/dist/index.d.ts +34 -16
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +32 -14
  109. package/dist/index.js.map +1 -1
  110. package/dist/prompts/prompts.d.ts +11 -0
  111. package/dist/prompts/prompts.d.ts.map +1 -0
  112. package/dist/prompts/prompts.js +272 -0
  113. package/dist/prompts/prompts.js.map +1 -0
  114. package/dist/storage/app-storage.d.ts +17 -12
  115. package/dist/storage/app-storage.d.ts.map +1 -1
  116. package/dist/storage/app-storage.js +13 -20
  117. package/dist/storage/app-storage.js.map +1 -1
  118. package/dist/storage/backends/indexeddb-storage-backend.d.ts +27 -0
  119. package/dist/storage/backends/indexeddb-storage-backend.d.ts.map +1 -0
  120. package/dist/storage/backends/indexeddb-storage-backend.js +166 -0
  121. package/dist/storage/backends/indexeddb-storage-backend.js.map +1 -0
  122. package/dist/storage/store.d.ts +23 -0
  123. package/dist/storage/store.d.ts.map +1 -0
  124. package/dist/storage/store.js +26 -0
  125. package/dist/storage/store.js.map +1 -0
  126. package/dist/storage/stores/provider-keys-store.d.ts +14 -0
  127. package/dist/storage/stores/provider-keys-store.d.ts.map +1 -0
  128. package/dist/storage/stores/provider-keys-store.js +27 -0
  129. package/dist/storage/stores/provider-keys-store.js.map +1 -0
  130. package/dist/storage/stores/sessions-store.d.ts +31 -0
  131. package/dist/storage/stores/sessions-store.d.ts.map +1 -0
  132. package/dist/storage/stores/sessions-store.js +113 -0
  133. package/dist/storage/stores/sessions-store.js.map +1 -0
  134. package/dist/storage/stores/settings-store.d.ts +14 -0
  135. package/dist/storage/stores/settings-store.d.ts.map +1 -0
  136. package/dist/storage/stores/settings-store.js +28 -0
  137. package/dist/storage/stores/settings-store.js.map +1 -0
  138. package/dist/storage/types.d.ts +156 -22
  139. package/dist/storage/types.d.ts.map +1 -1
  140. package/dist/tools/artifacts/ArtifactElement.d.ts +0 -1
  141. package/dist/tools/artifacts/ArtifactElement.d.ts.map +1 -1
  142. package/dist/tools/artifacts/ArtifactElement.js +0 -1
  143. package/dist/tools/artifacts/ArtifactElement.js.map +1 -1
  144. package/dist/tools/artifacts/ArtifactPill.d.ts +4 -0
  145. package/dist/tools/artifacts/ArtifactPill.d.ts.map +1 -0
  146. package/dist/tools/artifacts/ArtifactPill.js +22 -0
  147. package/dist/tools/artifacts/ArtifactPill.js.map +1 -0
  148. package/dist/tools/artifacts/Console.d.ts +18 -0
  149. package/dist/tools/artifacts/Console.d.ts.map +1 -0
  150. package/dist/tools/artifacts/Console.js +95 -0
  151. package/dist/tools/artifacts/Console.js.map +1 -0
  152. package/dist/tools/artifacts/DocxArtifact.d.ts +22 -0
  153. package/dist/tools/artifacts/DocxArtifact.d.ts.map +1 -0
  154. package/dist/tools/artifacts/DocxArtifact.js +208 -0
  155. package/dist/tools/artifacts/DocxArtifact.js.map +1 -0
  156. package/dist/tools/artifacts/ExcelArtifact.d.ts +24 -0
  157. package/dist/tools/artifacts/ExcelArtifact.d.ts.map +1 -0
  158. package/dist/tools/artifacts/ExcelArtifact.js +216 -0
  159. package/dist/tools/artifacts/ExcelArtifact.js.map +1 -0
  160. package/dist/tools/artifacts/GenericArtifact.d.ts +19 -0
  161. package/dist/tools/artifacts/GenericArtifact.d.ts.map +1 -0
  162. package/dist/tools/artifacts/GenericArtifact.js +117 -0
  163. package/dist/tools/artifacts/GenericArtifact.js.map +1 -0
  164. package/dist/tools/artifacts/HtmlArtifact.d.ts +8 -11
  165. package/dist/tools/artifacts/HtmlArtifact.d.ts.map +1 -1
  166. package/dist/tools/artifacts/HtmlArtifact.js +56 -88
  167. package/dist/tools/artifacts/HtmlArtifact.js.map +1 -1
  168. package/dist/tools/artifacts/ImageArtifact.d.ts +20 -0
  169. package/dist/tools/artifacts/ImageArtifact.d.ts.map +1 -0
  170. package/dist/tools/artifacts/ImageArtifact.js +120 -0
  171. package/dist/tools/artifacts/ImageArtifact.js.map +1 -0
  172. package/dist/tools/artifacts/MarkdownArtifact.d.ts +0 -1
  173. package/dist/tools/artifacts/MarkdownArtifact.d.ts.map +1 -1
  174. package/dist/tools/artifacts/MarkdownArtifact.js +0 -4
  175. package/dist/tools/artifacts/MarkdownArtifact.js.map +1 -1
  176. package/dist/tools/artifacts/PdfArtifact.d.ts +25 -0
  177. package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -0
  178. package/dist/tools/artifacts/PdfArtifact.js +184 -0
  179. package/dist/tools/artifacts/PdfArtifact.js.map +1 -0
  180. package/dist/tools/artifacts/SvgArtifact.d.ts +0 -1
  181. package/dist/tools/artifacts/SvgArtifact.d.ts.map +1 -1
  182. package/dist/tools/artifacts/SvgArtifact.js +0 -4
  183. package/dist/tools/artifacts/SvgArtifact.js.map +1 -1
  184. package/dist/tools/artifacts/TextArtifact.d.ts +0 -1
  185. package/dist/tools/artifacts/TextArtifact.d.ts.map +1 -1
  186. package/dist/tools/artifacts/TextArtifact.js +0 -4
  187. package/dist/tools/artifacts/TextArtifact.js.map +1 -1
  188. package/dist/tools/artifacts/artifacts-tool-renderer.d.ts +11 -0
  189. package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -0
  190. package/dist/tools/artifacts/artifacts-tool-renderer.js +262 -0
  191. package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -0
  192. package/dist/tools/artifacts/artifacts.d.ts +10 -13
  193. package/dist/tools/artifacts/artifacts.d.ts.map +1 -1
  194. package/dist/tools/artifacts/artifacts.js +166 -344
  195. package/dist/tools/artifacts/artifacts.js.map +1 -1
  196. package/dist/tools/artifacts/index.d.ts +1 -0
  197. package/dist/tools/artifacts/index.d.ts.map +1 -1
  198. package/dist/tools/artifacts/index.js +1 -0
  199. package/dist/tools/artifacts/index.js.map +1 -1
  200. package/dist/tools/extract-document.d.ts +24 -0
  201. package/dist/tools/extract-document.d.ts.map +1 -0
  202. package/dist/tools/extract-document.js +193 -0
  203. package/dist/tools/extract-document.js.map +1 -0
  204. package/dist/tools/index.d.ts +9 -7
  205. package/dist/tools/index.d.ts.map +1 -1
  206. package/dist/tools/index.js +17 -13
  207. package/dist/tools/index.js.map +1 -1
  208. package/dist/tools/javascript-repl.d.ts +16 -15
  209. package/dist/tools/javascript-repl.d.ts.map +1 -1
  210. package/dist/tools/javascript-repl.js +101 -133
  211. package/dist/tools/javascript-repl.js.map +1 -1
  212. package/dist/tools/renderer-registry.d.ts +12 -0
  213. package/dist/tools/renderer-registry.d.ts.map +1 -1
  214. package/dist/tools/renderer-registry.js +78 -0
  215. package/dist/tools/renderer-registry.js.map +1 -1
  216. package/dist/tools/renderers/BashRenderer.d.ts +2 -4
  217. package/dist/tools/renderers/BashRenderer.d.ts.map +1 -1
  218. package/dist/tools/renderers/BashRenderer.js +30 -26
  219. package/dist/tools/renderers/BashRenderer.js.map +1 -1
  220. package/dist/tools/renderers/CalculateRenderer.d.ts +2 -4
  221. package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -1
  222. package/dist/tools/renderers/CalculateRenderer.js +32 -28
  223. package/dist/tools/renderers/CalculateRenderer.js.map +1 -1
  224. package/dist/tools/renderers/DefaultRenderer.d.ts +2 -4
  225. package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -1
  226. package/dist/tools/renderers/DefaultRenderer.js +78 -18
  227. package/dist/tools/renderers/DefaultRenderer.js.map +1 -1
  228. package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts +2 -4
  229. package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -1
  230. package/dist/tools/renderers/GetCurrentTimeRenderer.js +57 -21
  231. package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -1
  232. package/dist/tools/types.d.ts +5 -2
  233. package/dist/tools/types.d.ts.map +1 -1
  234. package/dist/utils/i18n.d.ts +424 -1
  235. package/dist/utils/i18n.d.ts.map +1 -1
  236. package/dist/utils/i18n.js +131 -7
  237. package/dist/utils/i18n.js.map +1 -1
  238. package/example/package.json +2 -1
  239. package/example/src/custom-messages.ts +112 -0
  240. package/example/src/main.ts +391 -38
  241. package/package.json +48 -43
  242. package/scripts/count-prompt-tokens.ts +88 -0
  243. package/src/ChatPanel.ts +93 -101
  244. package/src/{state/agent-session.ts → agent/agent.ts} +80 -55
  245. package/src/{state → agent}/transports/AppTransport.ts +6 -6
  246. package/src/{state → agent}/transports/ProviderTransport.ts +13 -7
  247. package/src/{state → agent}/transports/types.ts +8 -2
  248. package/src/components/AgentInterface.ts +32 -16
  249. package/src/components/ConsoleBlock.ts +5 -1
  250. package/src/components/ExpandableSection.ts +46 -0
  251. package/src/components/MessageEditor.ts +159 -5
  252. package/src/components/MessageList.ts +18 -3
  253. package/src/components/Messages.ts +48 -89
  254. package/src/components/ProviderKeyInput.ts +6 -5
  255. package/src/components/SandboxedIframe.ts +412 -321
  256. package/src/components/message-renderer-registry.ts +28 -0
  257. package/src/components/sandbox/ArtifactsRuntimeProvider.ts +219 -0
  258. package/src/components/sandbox/AttachmentsRuntimeProvider.ts +66 -0
  259. package/src/components/sandbox/ConsoleRuntimeProvider.ts +187 -0
  260. package/src/components/sandbox/FileDownloadRuntimeProvider.ts +110 -0
  261. package/src/components/sandbox/RuntimeMessageBridge.ts +82 -0
  262. package/src/components/sandbox/RuntimeMessageRouter.ts +216 -0
  263. package/src/components/sandbox/SandboxRuntimeProvider.ts +35 -0
  264. package/src/dialogs/ApiKeyPromptDialog.ts +2 -5
  265. package/src/dialogs/ModelSelector.ts +2 -2
  266. package/src/dialogs/PersistentStorageDialog.ts +141 -0
  267. package/src/dialogs/SessionListDialog.ts +148 -0
  268. package/src/dialogs/SettingsDialog.ts +1 -0
  269. package/src/index.ts +61 -20
  270. package/src/prompts/prompts.ts +282 -0
  271. package/src/storage/app-storage.ts +27 -24
  272. package/src/storage/backends/indexeddb-storage-backend.ts +193 -0
  273. package/src/storage/store.ts +33 -0
  274. package/src/storage/stores/provider-keys-store.ts +33 -0
  275. package/src/storage/stores/sessions-store.ts +130 -0
  276. package/src/storage/stores/settings-store.ts +34 -0
  277. package/src/storage/types.ts +182 -22
  278. package/src/tools/artifacts/ArtifactElement.ts +0 -1
  279. package/src/tools/artifacts/ArtifactPill.ts +25 -0
  280. package/src/tools/artifacts/Console.ts +93 -0
  281. package/src/tools/artifacts/DocxArtifact.ts +213 -0
  282. package/src/tools/artifacts/ExcelArtifact.ts +231 -0
  283. package/src/tools/artifacts/GenericArtifact.ts +117 -0
  284. package/src/tools/artifacts/HtmlArtifact.ts +64 -94
  285. package/src/tools/artifacts/ImageArtifact.ts +116 -0
  286. package/src/tools/artifacts/MarkdownArtifact.ts +0 -1
  287. package/src/tools/artifacts/PdfArtifact.ts +201 -0
  288. package/src/tools/artifacts/SvgArtifact.ts +0 -1
  289. package/src/tools/artifacts/TextArtifact.ts +0 -1
  290. package/src/tools/artifacts/artifacts-tool-renderer.ts +298 -0
  291. package/src/tools/artifacts/artifacts.ts +190 -366
  292. package/src/tools/artifacts/index.ts +1 -0
  293. package/src/tools/extract-document.ts +250 -0
  294. package/src/tools/index.ts +25 -14
  295. package/src/tools/javascript-repl.ts +138 -160
  296. package/src/tools/renderer-registry.ts +98 -0
  297. package/src/tools/renderers/BashRenderer.ts +33 -30
  298. package/src/tools/renderers/CalculateRenderer.ts +36 -31
  299. package/src/tools/renderers/DefaultRenderer.ts +84 -21
  300. package/src/tools/renderers/GetCurrentTimeRenderer.ts +68 -23
  301. package/src/tools/types.ts +10 -2
  302. package/src/utils/i18n.ts +203 -8
  303. package/dist/state/agent-session.d.ts.map +0 -1
  304. package/dist/state/agent-session.js.map +0 -1
  305. package/dist/state/transports/AppTransport.d.ts.map +0 -1
  306. package/dist/state/transports/ProviderTransport.d.ts.map +0 -1
  307. package/dist/state/transports/ProviderTransport.js.map +0 -1
  308. package/dist/state/transports/index.js.map +0 -1
  309. package/dist/state/transports/proxy-types.js.map +0 -1
  310. package/dist/state/transports/types.d.ts +0 -11
  311. package/dist/state/transports/types.d.ts.map +0 -1
  312. package/dist/storage/backends/chrome-storage-backend.d.ts +0 -18
  313. package/dist/storage/backends/chrome-storage-backend.d.ts.map +0 -1
  314. package/dist/storage/backends/chrome-storage-backend.js +0 -67
  315. package/dist/storage/backends/chrome-storage-backend.js.map +0 -1
  316. package/dist/storage/backends/indexeddb-backend.d.ts +0 -20
  317. package/dist/storage/backends/indexeddb-backend.d.ts.map +0 -1
  318. package/dist/storage/backends/indexeddb-backend.js +0 -89
  319. package/dist/storage/backends/indexeddb-backend.js.map +0 -1
  320. package/dist/storage/backends/local-storage-backend.d.ts +0 -18
  321. package/dist/storage/backends/local-storage-backend.d.ts.map +0 -1
  322. package/dist/storage/backends/local-storage-backend.js +0 -69
  323. package/dist/storage/backends/local-storage-backend.js.map +0 -1
  324. package/dist/storage/repositories/provider-keys-repository.d.ts +0 -34
  325. package/dist/storage/repositories/provider-keys-repository.d.ts.map +0 -1
  326. package/dist/storage/repositories/provider-keys-repository.js +0 -50
  327. package/dist/storage/repositories/provider-keys-repository.js.map +0 -1
  328. package/dist/storage/repositories/settings-repository.d.ts +0 -34
  329. package/dist/storage/repositories/settings-repository.d.ts.map +0 -1
  330. package/dist/storage/repositories/settings-repository.js +0 -46
  331. package/dist/storage/repositories/settings-repository.js.map +0 -1
  332. package/src/storage/backends/chrome-storage-backend.ts +0 -82
  333. package/src/storage/backends/indexeddb-backend.ts +0 -107
  334. package/src/storage/backends/local-storage-backend.ts +0 -74
  335. package/src/storage/repositories/provider-keys-repository.ts +0 -55
  336. package/src/storage/repositories/settings-repository.ts +0 -51
  337. /package/dist/{state → agent}/transports/index.d.ts +0 -0
  338. /package/dist/{state → agent}/transports/index.js +0 -0
  339. /package/dist/{state → agent}/transports/proxy-types.d.ts +0 -0
  340. /package/dist/{state → agent}/transports/proxy-types.js +0 -0
  341. /package/dist/{state → agent}/transports/types.js +0 -0
  342. /package/dist/{state → agent}/types.d.ts +0 -0
  343. /package/dist/{state → agent}/types.js +0 -0
  344. /package/src/{state → agent}/transports/index.ts +0 -0
  345. /package/src/{state → agent}/transports/proxy-types.ts +0 -0
  346. /package/src/{state → agent}/types.ts +0 -0
@@ -1,25 +1,37 @@
1
- import { Button, Diff, icon } from "@mariozechner/mini-lit";
2
- import { type AgentTool, type Message, StringEnum, type ToolCall, type ToolResultMessage } from "@mariozechner/pi-ai";
1
+ import { Button, icon } from "@mariozechner/mini-lit";
2
+ import "@mariozechner/mini-lit/dist/MarkdownBlock.js";
3
+ import { type AgentTool, type Message, StringEnum, type ToolCall } from "@mariozechner/pi-ai";
3
4
  import { type Static, Type } from "@sinclair/typebox";
4
5
  import { html, LitElement, type TemplateResult } from "lit";
5
6
  import { customElement, property, state } from "lit/decorators.js";
6
7
  import { createRef, type Ref, ref } from "lit/directives/ref.js";
7
8
  import { X } from "lucide";
9
+ import type { Agent } from "../../agent/agent.js";
10
+ import type { ArtifactMessage } from "../../components/Messages.js";
11
+ import { ArtifactsRuntimeProvider } from "../../components/sandbox/ArtifactsRuntimeProvider.js";
12
+ import { AttachmentsRuntimeProvider } from "../../components/sandbox/AttachmentsRuntimeProvider.js";
13
+ import type { SandboxRuntimeProvider } from "../../components/sandbox/SandboxRuntimeProvider.js";
14
+ import {
15
+ ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO,
16
+ ARTIFACTS_TOOL_DESCRIPTION,
17
+ ATTACHMENTS_RUNTIME_DESCRIPTION,
18
+ } from "../../prompts/prompts.js";
8
19
  import type { Attachment } from "../../utils/attachment-utils.js";
9
20
  import { i18n } from "../../utils/i18n.js";
10
- import type { ToolRenderer } from "../types.js";
11
21
  import type { ArtifactElement } from "./ArtifactElement.js";
22
+ import { DocxArtifact } from "./DocxArtifact.js";
23
+ import { ExcelArtifact } from "./ExcelArtifact.js";
24
+ import { GenericArtifact } from "./GenericArtifact.js";
12
25
  import { HtmlArtifact } from "./HtmlArtifact.js";
26
+ import { ImageArtifact } from "./ImageArtifact.js";
13
27
  import { MarkdownArtifact } from "./MarkdownArtifact.js";
28
+ import { PdfArtifact } from "./PdfArtifact.js";
14
29
  import { SvgArtifact } from "./SvgArtifact.js";
15
30
  import { TextArtifact } from "./TextArtifact.js";
16
- import "@mariozechner/mini-lit/dist/MarkdownBlock.js";
17
- import "@mariozechner/mini-lit/dist/CodeBlock.js";
18
31
 
19
32
  // Simple artifact model
20
33
  export interface Artifact {
21
34
  filename: string;
22
- title: string;
23
35
  content: string;
24
36
  createdAt: Date;
25
37
  updatedAt: Date;
@@ -31,20 +43,14 @@ const artifactsParamsSchema = Type.Object({
31
43
  description: "The operation to perform",
32
44
  }),
33
45
  filename: Type.String({ description: "Filename including extension (e.g., 'index.html', 'script.js')" }),
34
- title: Type.Optional(Type.String({ description: "Display title for the tab (defaults to filename)" })),
35
46
  content: Type.Optional(Type.String({ description: "File content" })),
36
47
  old_str: Type.Optional(Type.String({ description: "String to replace (for update command)" })),
37
48
  new_str: Type.Optional(Type.String({ description: "Replacement string (for update command)" })),
38
49
  });
39
50
  export type ArtifactsParams = Static<typeof artifactsParamsSchema>;
40
51
 
41
- // Minimal helper to render plain text outputs consistently
42
- function plainOutput(text: string): TemplateResult {
43
- return html`<div class="text-xs text-muted-foreground whitespace-pre-wrap font-mono">${text}</div>`;
44
- }
45
-
46
52
  @customElement("artifacts-panel")
47
- export class ArtifactsPanel extends LitElement implements ToolRenderer<ArtifactsParams, undefined> {
53
+ export class ArtifactsPanel extends LitElement {
48
54
  @state() private _artifacts = new Map<string, Artifact>();
49
55
  @state() private _activeFilename: string | null = null;
50
56
 
@@ -52,8 +58,8 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
52
58
  private artifactElements = new Map<string, ArtifactElement>();
53
59
  private contentRef: Ref<HTMLDivElement> = createRef();
54
60
 
55
- // External provider for attachments (decouples panel from AgentInterface)
56
- @property({ attribute: false }) attachmentsProvider?: () => Attachment[];
61
+ // Agent reference (needed to get attachments for HTML artifacts)
62
+ @property({ attribute: false }) agent?: Agent;
57
63
  // Sandbox URL provider for browser extensions (optional)
58
64
  @property({ attribute: false }) sandboxUrlProvider?: () => string;
59
65
  // Callbacks
@@ -70,6 +76,29 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
70
76
  return this._artifacts;
71
77
  }
72
78
 
79
+ // Get runtime providers for HTML artifacts (read-only: attachments + artifacts)
80
+ private getHtmlArtifactRuntimeProviders(): SandboxRuntimeProvider[] {
81
+ const providers: SandboxRuntimeProvider[] = [];
82
+
83
+ // Get attachments from agent messages
84
+ if (this.agent) {
85
+ const attachments: Attachment[] = [];
86
+ for (const message of this.agent.state.messages) {
87
+ if (message.role === "user" && message.attachments) {
88
+ attachments.push(...message.attachments);
89
+ }
90
+ }
91
+ if (attachments.length > 0) {
92
+ providers.push(new AttachmentsRuntimeProvider(attachments));
93
+ }
94
+ }
95
+
96
+ // Add read-only artifacts provider
97
+ providers.push(new ArtifactsRuntimeProvider(this, this.agent, false));
98
+
99
+ return providers;
100
+ }
101
+
73
102
  protected override createRenderRoot(): HTMLElement | DocumentFragment {
74
103
  return this; // light DOM for shared styles
75
104
  }
@@ -99,60 +128,63 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
99
128
  }
100
129
 
101
130
  // Helper to determine file type from extension
102
- private getFileType(filename: string): "html" | "svg" | "markdown" | "text" {
131
+ private getFileType(
132
+ filename: string,
133
+ ): "html" | "svg" | "markdown" | "image" | "pdf" | "excel" | "docx" | "text" | "generic" {
103
134
  const ext = filename.split(".").pop()?.toLowerCase();
104
135
  if (ext === "html") return "html";
105
136
  if (ext === "svg") return "svg";
106
137
  if (ext === "md" || ext === "markdown") return "markdown";
107
- return "text";
108
- }
109
-
110
- // Helper to determine language for syntax highlighting
111
- private getLanguageFromFilename(filename?: string): string {
112
- if (!filename) return "text";
113
- const ext = filename.split(".").pop()?.toLowerCase();
114
- const languageMap: Record<string, string> = {
115
- js: "javascript",
116
- jsx: "javascript",
117
- ts: "typescript",
118
- tsx: "typescript",
119
- html: "html",
120
- css: "css",
121
- scss: "scss",
122
- json: "json",
123
- py: "python",
124
- md: "markdown",
125
- svg: "xml",
126
- xml: "xml",
127
- yaml: "yaml",
128
- yml: "yaml",
129
- sh: "bash",
130
- bash: "bash",
131
- sql: "sql",
132
- java: "java",
133
- c: "c",
134
- cpp: "cpp",
135
- cs: "csharp",
136
- go: "go",
137
- rs: "rust",
138
- php: "php",
139
- rb: "ruby",
140
- swift: "swift",
141
- kt: "kotlin",
142
- r: "r",
143
- };
144
- return languageMap[ext || ""] || "text";
138
+ if (ext === "pdf") return "pdf";
139
+ if (ext === "xlsx" || ext === "xls") return "excel";
140
+ if (ext === "docx") return "docx";
141
+ if (
142
+ ext === "png" ||
143
+ ext === "jpg" ||
144
+ ext === "jpeg" ||
145
+ ext === "gif" ||
146
+ ext === "webp" ||
147
+ ext === "bmp" ||
148
+ ext === "ico"
149
+ )
150
+ return "image";
151
+ // Text files
152
+ if (
153
+ ext === "txt" ||
154
+ ext === "json" ||
155
+ ext === "xml" ||
156
+ ext === "yaml" ||
157
+ ext === "yml" ||
158
+ ext === "csv" ||
159
+ ext === "js" ||
160
+ ext === "ts" ||
161
+ ext === "jsx" ||
162
+ ext === "tsx" ||
163
+ ext === "py" ||
164
+ ext === "java" ||
165
+ ext === "c" ||
166
+ ext === "cpp" ||
167
+ ext === "h" ||
168
+ ext === "css" ||
169
+ ext === "scss" ||
170
+ ext === "sass" ||
171
+ ext === "less" ||
172
+ ext === "sh"
173
+ )
174
+ return "text";
175
+ // Everything else gets generic fallback
176
+ return "generic";
145
177
  }
146
178
 
147
179
  // Get or create artifact element
148
- private getOrCreateArtifactElement(filename: string, content: string, title: string): ArtifactElement {
180
+ private getOrCreateArtifactElement(filename: string, content: string): ArtifactElement {
149
181
  let element = this.artifactElements.get(filename);
150
182
 
151
183
  if (!element) {
152
184
  const type = this.getFileType(filename);
153
185
  if (type === "html") {
154
186
  element = new HtmlArtifact();
155
- (element as HtmlArtifact).attachments = this.attachmentsProvider?.() || [];
187
+ (element as HtmlArtifact).runtimeProviders = this.getHtmlArtifactRuntimeProviders();
156
188
  if (this.sandboxUrlProvider) {
157
189
  (element as HtmlArtifact).sandboxUrlProvider = this.sandboxUrlProvider;
158
190
  }
@@ -160,11 +192,20 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
160
192
  element = new SvgArtifact();
161
193
  } else if (type === "markdown") {
162
194
  element = new MarkdownArtifact();
163
- } else {
195
+ } else if (type === "image") {
196
+ element = new ImageArtifact();
197
+ } else if (type === "pdf") {
198
+ element = new PdfArtifact();
199
+ } else if (type === "excel") {
200
+ element = new ExcelArtifact();
201
+ } else if (type === "docx") {
202
+ element = new DocxArtifact();
203
+ } else if (type === "text") {
164
204
  element = new TextArtifact();
205
+ } else {
206
+ element = new GenericArtifact();
165
207
  }
166
208
  element.filename = filename;
167
- element.displayTitle = title;
168
209
  element.content = content;
169
210
  element.style.display = "none";
170
211
  element.style.height = "100%";
@@ -186,9 +227,8 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
186
227
  } else {
187
228
  // Just update content
188
229
  element.content = content;
189
- element.displayTitle = title;
190
230
  if (element instanceof HtmlArtifact) {
191
- element.attachments = this.attachmentsProvider?.() || [];
231
+ element.runtimeProviders = this.getHtmlArtifactRuntimeProviders();
192
232
  }
193
233
  }
194
234
 
@@ -208,10 +248,18 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
208
248
  });
209
249
  this._activeFilename = filename;
210
250
  this.requestUpdate(); // Only for tab bar update
251
+
252
+ // Scroll the active tab into view after render
253
+ requestAnimationFrame(() => {
254
+ const activeButton = this.querySelector(`button[data-filename="${filename}"]`);
255
+ if (activeButton) {
256
+ activeButton.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
257
+ }
258
+ });
211
259
  }
212
260
 
213
261
  // Open panel and focus an artifact tab by filename
214
- private openArtifact(filename: string) {
262
+ public openArtifact(filename: string) {
215
263
  if (this._artifacts.has(filename)) {
216
264
  this.showArtifact(filename);
217
265
  // Ask host to open panel (AgentInterface demo listens to onOpen)
@@ -224,103 +272,14 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
224
272
  return {
225
273
  label: "Artifacts",
226
274
  name: "artifacts",
227
- description: `Creates and manages file artifacts. Each artifact is a file with a filename and content.
228
-
229
- IMPORTANT: Always prefer updating existing files over creating new ones. Check available files first.
230
-
231
- Commands:
232
- 1. create: Create a new file
233
- - filename: Name with extension (required, e.g., 'index.html', 'script.js', 'README.md')
234
- - title: Display name for the tab (optional, defaults to filename)
235
- - content: File content (required)
236
-
237
- 2. update: Update part of an existing file
238
- - filename: File to update (required)
239
- - old_str: Exact string to replace (required)
240
- - new_str: Replacement string (required)
241
-
242
- 3. rewrite: Completely replace a file's content
243
- - filename: File to rewrite (required)
244
- - content: New content (required)
245
- - title: Optionally update display title
246
-
247
- 4. get: Retrieve the full content of a file
248
- - filename: File to retrieve (required)
249
- - Returns the complete file content
250
-
251
- 5. delete: Delete a file
252
- - filename: File to delete (required)
253
-
254
- 6. logs: Get console logs and errors (HTML files only)
255
- - filename: HTML file to get logs for (required)
256
- - Returns all console output and runtime errors
257
-
258
- For text/html artifacts with attachments:
259
- - HTML artifacts automatically have access to user attachments via JavaScript
260
- - Available global functions in HTML artifacts:
261
- * listFiles() - Returns array of {id, fileName, mimeType, size} for all attachments
262
- * readTextFile(attachmentId) - Returns text content of attachment (for CSV, JSON, text files)
263
- * readBinaryFile(attachmentId) - Returns Uint8Array of binary data (for images, Excel, etc.)
264
- - Example HTML artifact that processes a CSV attachment:
265
- <script>
266
- // List available files
267
- const files = listFiles();
268
- console.log('Available files:', files);
269
-
270
- // Find CSV file
271
- const csvFile = files.find(f => f.mimeType === 'text/csv');
272
- if (csvFile) {
273
- const csvContent = readTextFile(csvFile.id);
274
- // Process CSV data...
275
- }
276
-
277
- // Display image
278
- const imageFile = files.find(f => f.mimeType.startsWith('image/'));
279
- if (imageFile) {
280
- const bytes = readBinaryFile(imageFile.id);
281
- const blob = new Blob([bytes], {type: imageFile.mimeType});
282
- const url = URL.createObjectURL(blob);
283
- document.body.innerHTML = '<img src="' + url + '">';
284
- }
285
- </script>
286
-
287
- For text/html artifacts:
288
- - Must be a single self-contained file
289
- - External scripts: Use CDNs like https://esm.sh, https://unpkg.com, or https://cdnjs.cloudflare.com
290
- - Preferred: Use https://esm.sh for npm packages (e.g., https://esm.sh/three for Three.js)
291
- - For ES modules, use: <script type="module">import * as THREE from 'https://esm.sh/three';</script>
292
- - For Three.js specifically: import from 'https://esm.sh/three' or 'https://esm.sh/three@0.160.0'
293
- - For addons: import from 'https://esm.sh/three/examples/jsm/controls/OrbitControls.js'
294
- - No localStorage/sessionStorage - use in-memory variables only
295
- - CSS should be included inline
296
- - CRITICAL REMINDER FOR HTML ARTIFACTS:
297
- - ALWAYS set a background color inline in <style> or directly on body element
298
- - Failure to set a background color is a COMPLIANCE ERROR
299
- - Background color MUST be explicitly defined to ensure visibility and proper rendering
300
- - Can embed base64 images directly in img tags
301
- - Ensure the layout is responsive as the iframe might be resized
302
- - Note: Network errors (404s) for external scripts may not be captured in logs due to browser security
303
-
304
- For application/vnd.ant.code artifacts:
305
- - Include the language parameter for syntax highlighting
306
- - Supports all major programming languages
307
-
308
- For text/markdown:
309
- - Standard markdown syntax
310
- - Will be rendered with full formatting
311
- - Can include base64 images using markdown syntax
312
-
313
- For image/svg+xml:
314
- - Complete SVG markup
315
- - Will be rendered inline
316
- - Can embed raster images as base64 in SVG
317
-
318
- CRITICAL REMINDER FOR ALL ARTIFACTS:
319
- - Prefer to update existing files rather than creating new ones
320
- - Keep filenames consistent and descriptive
321
- - Use appropriate file extensions
322
- - Ensure HTML artifacts have a defined background color
323
- `,
275
+ get description() {
276
+ // HTML artifacts have read-only access to attachments and artifacts
277
+ const runtimeProviderDescriptions = [
278
+ ATTACHMENTS_RUNTIME_DESCRIPTION,
279
+ ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO,
280
+ ];
281
+ return ARTIFACTS_TOOL_DESCRIPTION(runtimeProviderDescriptions);
282
+ },
324
283
  parameters: artifactsParamsSchema,
325
284
  // Execute mutates our local store and returns a plain output
326
285
  execute: async (_toolCallId: string, args: Static<typeof artifactsParamsSchema>, _signal?: AbortSignal) => {
@@ -330,155 +289,10 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
330
289
  };
331
290
  }
332
291
 
333
- // ToolRenderer implementation
334
- renderParams(params: ArtifactsParams, isStreaming?: boolean): TemplateResult {
335
- if (isStreaming && !params.command) {
336
- return html`<div class="text-sm text-muted-foreground">${i18n("Processing artifact...")}</div>`;
337
- }
338
-
339
- let commandLabel = i18n("Processing");
340
- if (params.command) {
341
- switch (params.command) {
342
- case "create":
343
- commandLabel = i18n("Create");
344
- break;
345
- case "update":
346
- commandLabel = i18n("Update");
347
- break;
348
- case "rewrite":
349
- commandLabel = i18n("Rewrite");
350
- break;
351
- case "get":
352
- commandLabel = i18n("Get");
353
- break;
354
- case "delete":
355
- commandLabel = i18n("Delete");
356
- break;
357
- case "logs":
358
- commandLabel = i18n("Get logs");
359
- break;
360
- default:
361
- commandLabel = params.command.charAt(0).toUpperCase() + params.command.slice(1);
362
- }
363
- }
364
- const filename = params.filename || "";
365
-
366
- switch (params.command) {
367
- case "create":
368
- return html`
369
- <div
370
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
371
- @click=${() => this.openArtifact(params.filename)}
372
- >
373
- <div>
374
- <span class="font-medium">${i18n("Create")}</span>
375
- <span class="text-muted-foreground ml-1">${filename}</span>
376
- </div>
377
- ${
378
- params.content
379
- ? html`<code-block
380
- .code=${params.content}
381
- language=${this.getLanguageFromFilename(params.filename)}
382
- class="mt-2"
383
- ></code-block>`
384
- : ""
385
- }
386
- </div>
387
- `;
388
- case "update":
389
- return html`
390
- <div
391
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
392
- @click=${() => this.openArtifact(params.filename)}
393
- >
394
- <div>
395
- <span class="font-medium">${i18n("Update")}</span>
396
- <span class="text-muted-foreground ml-1">${filename}</span>
397
- </div>
398
- ${
399
- params.old_str !== undefined && params.new_str !== undefined
400
- ? Diff({ oldText: params.old_str, newText: params.new_str, className: "mt-2" })
401
- : ""
402
- }
403
- </div>
404
- `;
405
- case "rewrite":
406
- return html`
407
- <div
408
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
409
- @click=${() => this.openArtifact(params.filename)}
410
- >
411
- <div>
412
- <span class="font-medium">${i18n("Rewrite")}</span>
413
- <span class="text-muted-foreground ml-1">${filename}</span>
414
- </div>
415
- ${
416
- params.content
417
- ? html`<code-block
418
- .code=${params.content}
419
- language=${this.getLanguageFromFilename(params.filename)}
420
- class="mt-2"
421
- ></code-block>`
422
- : ""
423
- }
424
- </div>
425
- `;
426
- case "get":
427
- return html`
428
- <div
429
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
430
- @click=${() => this.openArtifact(params.filename)}
431
- >
432
- <span class="font-medium">${i18n("Get")}</span>
433
- <span class="text-muted-foreground ml-1">${filename}</span>
434
- </div>
435
- `;
436
- case "delete":
437
- return html`
438
- <div
439
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
440
- @click=${() => this.openArtifact(params.filename)}
441
- >
442
- <span class="font-medium">${i18n("Delete")}</span>
443
- <span class="text-muted-foreground ml-1">${filename}</span>
444
- </div>
445
- `;
446
- case "logs":
447
- return html`
448
- <div
449
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
450
- @click=${() => this.openArtifact(params.filename)}
451
- >
452
- <span class="font-medium">${i18n("Get logs")}</span>
453
- <span class="text-muted-foreground ml-1">${filename}</span>
454
- </div>
455
- `;
456
- default:
457
- // Fallback for any command not yet handled during streaming
458
- return html`
459
- <div
460
- class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
461
- @click=${() => this.openArtifact(params.filename)}
462
- >
463
- <span class="font-medium">${commandLabel}</span>
464
- <span class="text-muted-foreground ml-1">${filename}</span>
465
- </div>
466
- `;
467
- }
468
- }
469
-
470
- renderResult(params: ArtifactsParams, result: ToolResultMessage<undefined>): TemplateResult {
471
- // Make result clickable to focus the referenced file when applicable
472
- const content = result.output || i18n("(no output)");
473
- return html`
474
- <div class="cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1" @click=${() => this.openArtifact(params.filename)}>
475
- ${plainOutput(content)}
476
- </div>
477
- `;
478
- }
479
-
480
292
  // Re-apply artifacts by scanning a message list (optional utility)
481
- public async reconstructFromMessages(messages: Array<Message | { role: "aborted" }>): Promise<void> {
293
+ public async reconstructFromMessages(
294
+ messages: Array<Message | { role: "aborted" } | { role: "artifact" }>,
295
+ ): Promise<void> {
482
296
  const toolCalls = new Map<string, ToolCall>();
483
297
  const artifactToolName = "artifacts";
484
298
 
@@ -496,7 +310,33 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
496
310
  // 2) Build an ordered list of successful artifact operations
497
311
  const operations: Array<ArtifactsParams> = [];
498
312
  for (const m of messages) {
499
- if ((m as any).role === "toolResult" && (m as any).toolName === artifactToolName && !(m as any).isError) {
313
+ if ((m as any).role === "artifact") {
314
+ const artifactMsg = m as ArtifactMessage;
315
+ switch (artifactMsg.action) {
316
+ case "create":
317
+ operations.push({
318
+ command: "create",
319
+ filename: artifactMsg.filename,
320
+ content: artifactMsg.content,
321
+ });
322
+ break;
323
+ case "update":
324
+ operations.push({
325
+ command: "rewrite",
326
+ filename: artifactMsg.filename,
327
+ content: artifactMsg.content,
328
+ });
329
+ break;
330
+ case "delete":
331
+ operations.push({
332
+ command: "delete",
333
+ filename: artifactMsg.filename,
334
+ });
335
+ break;
336
+ }
337
+ }
338
+ // Handle tool result messages (from artifacts tool calls)
339
+ else if ((m as any).role === "toolResult" && (m as any).toolName === artifactToolName && !(m as any).isError) {
500
340
  const toolCallId = (m as any).toolCallId as string;
501
341
  const call = toolCalls.get(toolCallId);
502
342
  if (!call) continue;
@@ -507,30 +347,27 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
507
347
  }
508
348
 
509
349
  // 3) Compute final state per filename by simulating operations in-memory
510
- type FinalArtifact = { title: string; content: string };
511
- const finalArtifacts = new Map<string, FinalArtifact>();
350
+ const finalArtifacts = new Map<string, string>();
512
351
  for (const op of operations) {
513
352
  const filename = op.filename;
514
353
  switch (op.command) {
515
354
  case "create": {
516
355
  if (op.content) {
517
- finalArtifacts.set(filename, { title: op.title || filename, content: op.content });
356
+ finalArtifacts.set(filename, op.content);
518
357
  }
519
358
  break;
520
359
  }
521
360
  case "rewrite": {
522
361
  if (op.content) {
523
- // If file didn't exist earlier but rewrite succeeded, treat as fresh content
524
- const existing = finalArtifacts.get(filename);
525
- finalArtifacts.set(filename, { title: op.title || existing?.title || filename, content: op.content });
362
+ finalArtifacts.set(filename, op.content);
526
363
  }
527
364
  break;
528
365
  }
529
366
  case "update": {
530
- const existing = finalArtifacts.get(filename);
367
+ let existing = finalArtifacts.get(filename);
531
368
  if (!existing) break; // skip invalid update (shouldn't happen for successful results)
532
369
  if (op.old_str !== undefined && op.new_str !== undefined) {
533
- existing.content = existing.content.replace(op.old_str, op.new_str);
370
+ existing = existing.replace(op.old_str, op.new_str);
534
371
  finalArtifacts.set(filename, existing);
535
372
  }
536
373
  break;
@@ -556,8 +393,8 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
556
393
  this._artifacts = new Map(this._artifacts);
557
394
 
558
395
  // 5) Create artifacts in a single pass without waiting for iframe execution or tab switching
559
- for (const [filename, { title, content }] of finalArtifacts.entries()) {
560
- const createParams: ArtifactsParams = { command: "create", filename, title, content } as const;
396
+ for (const [filename, content] of finalArtifacts.entries()) {
397
+ const createParams: ArtifactsParams = { command: "create", filename, content } as const;
561
398
  try {
562
399
  await this.createArtifact(createParams, { skipWait: true, silent: true });
563
400
  } catch {
@@ -605,50 +442,27 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
605
442
  }
606
443
 
607
444
  return new Promise((resolve) => {
608
- let resolved = false;
609
-
610
- // Listen for the execution-complete message
611
- const messageHandler = (event: MessageEvent) => {
612
- if (event.data?.type === "execution-complete" && event.data?.artifactId === filename) {
613
- if (!resolved) {
614
- resolved = true;
615
- window.removeEventListener("message", messageHandler);
616
-
617
- // Get the logs from the element
618
- const logs = element.getLogs();
619
- if (logs.includes("[error]")) {
620
- resolve(`\n\nExecution completed with errors:\n${logs}`);
621
- } else if (logs !== `No logs for ${filename}`) {
622
- resolve(`\n\nExecution logs:\n${logs}`);
623
- } else {
624
- resolve("");
625
- }
626
- }
627
- }
628
- };
629
-
630
- window.addEventListener("message", messageHandler);
631
-
632
- // Fallback timeout in case the message never arrives
445
+ // Fallback timeout - just get logs after execution should complete
633
446
  setTimeout(() => {
634
- if (!resolved) {
635
- resolved = true;
636
- window.removeEventListener("message", messageHandler);
637
-
638
- // Get whatever logs we have so far
639
- const logs = element.getLogs();
640
- if (logs.includes("[error]")) {
641
- resolve(`\n\nExecution timed out with errors:\n${logs}`);
642
- } else if (logs !== `No logs for ${filename}`) {
643
- resolve(`\n\nExecution timed out. Partial logs:\n${logs}`);
644
- } else {
645
- resolve("");
646
- }
647
- }
447
+ // Get whatever logs we have
448
+ const logs = element.getLogs();
449
+ resolve(logs);
648
450
  }, 1500);
649
451
  });
650
452
  }
651
453
 
454
+ // Reload all HTML artifacts (called when any artifact changes)
455
+ private reloadAllHtmlArtifacts() {
456
+ this.artifactElements.forEach((element) => {
457
+ if (element instanceof HtmlArtifact && element.sandboxIframeRef.value) {
458
+ // Update runtime providers with latest artifact state
459
+ element.runtimeProviders = this.getHtmlArtifactRuntimeProviders();
460
+ // Re-execute the HTML content
461
+ element.executeContent(element.content);
462
+ }
463
+ });
464
+ }
465
+
652
466
  private async createArtifact(
653
467
  params: ArtifactsParams,
654
468
  options: { skipWait?: boolean; silent?: boolean } = {},
@@ -660,10 +474,8 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
660
474
  return `Error: File ${params.filename} already exists`;
661
475
  }
662
476
 
663
- const title = params.title || params.filename;
664
477
  const artifact: Artifact = {
665
478
  filename: params.filename,
666
- title: title,
667
479
  content: params.content,
668
480
  createdAt: new Date(),
669
481
  updatedAt: new Date(),
@@ -672,18 +484,21 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
672
484
  this._artifacts = new Map(this._artifacts);
673
485
 
674
486
  // Create or update element
675
- this.getOrCreateArtifactElement(params.filename, params.content, title);
487
+ this.getOrCreateArtifactElement(params.filename, params.content);
676
488
  if (!options.silent) {
677
489
  this.showArtifact(params.filename);
678
490
  this.onArtifactsChange?.();
679
491
  this.requestUpdate();
680
492
  }
681
493
 
494
+ // Reload all HTML artifacts since they might depend on this new artifact
495
+ this.reloadAllHtmlArtifacts();
496
+
682
497
  // For HTML files, wait for execution
683
498
  let result = `Created file ${params.filename}`;
684
499
  if (this.getFileType(params.filename) === "html" && !options.skipWait) {
685
500
  const logs = await this.waitForHtmlExecution(params.filename);
686
- result += logs;
501
+ result += `\n${logs}`;
687
502
  }
688
503
 
689
504
  return result;
@@ -711,7 +526,7 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
711
526
  this._artifacts.set(params.filename, artifact);
712
527
 
713
528
  // Update element
714
- this.getOrCreateArtifactElement(params.filename, artifact.content, artifact.title);
529
+ this.getOrCreateArtifactElement(params.filename, artifact.content);
715
530
  if (!options.silent) {
716
531
  this.onArtifactsChange?.();
717
532
  this.requestUpdate();
@@ -720,11 +535,14 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
720
535
  // Show the artifact
721
536
  this.showArtifact(params.filename);
722
537
 
538
+ // Reload all HTML artifacts since they might depend on this updated artifact
539
+ this.reloadAllHtmlArtifacts();
540
+
723
541
  // For HTML files, wait for execution
724
542
  let result = `Updated file ${params.filename}`;
725
543
  if (this.getFileType(params.filename) === "html" && !options.skipWait) {
726
544
  const logs = await this.waitForHtmlExecution(params.filename);
727
- result += logs;
545
+ result += `\n${logs}`;
728
546
  }
729
547
 
730
548
  return result;
@@ -745,12 +563,11 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
745
563
  }
746
564
 
747
565
  artifact.content = params.content;
748
- if (params.title) artifact.title = params.title;
749
566
  artifact.updatedAt = new Date();
750
567
  this._artifacts.set(params.filename, artifact);
751
568
 
752
569
  // Update element
753
- this.getOrCreateArtifactElement(params.filename, artifact.content, artifact.title);
570
+ this.getOrCreateArtifactElement(params.filename, artifact.content);
754
571
  if (!options.silent) {
755
572
  this.onArtifactsChange?.();
756
573
  }
@@ -758,11 +575,14 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
758
575
  // Show the artifact
759
576
  this.showArtifact(params.filename);
760
577
 
578
+ // Reload all HTML artifacts since they might depend on this rewritten artifact
579
+ this.reloadAllHtmlArtifacts();
580
+
761
581
  // For HTML files, wait for execution
762
- let result = `Rewrote file ${params.filename}`;
582
+ let result = "";
763
583
  if (this.getFileType(params.filename) === "html" && !options.skipWait) {
764
584
  const logs = await this.waitForHtmlExecution(params.filename);
765
- result += logs;
585
+ result += `\n${logs}`;
766
586
  }
767
587
 
768
588
  return result;
@@ -809,6 +629,9 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
809
629
  this.onArtifactsChange?.();
810
630
  this.requestUpdate();
811
631
 
632
+ // Reload all HTML artifacts since they might have depended on this deleted artifact
633
+ this.reloadAllHtmlArtifacts();
634
+
812
635
  return `Deleted file ${params.filename}`;
813
636
  }
814
637
 
@@ -852,6 +675,7 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
852
675
  return html`
853
676
  <button
854
677
  class="px-3 py-2 whitespace-nowrap border-b-2 ${activeClass}"
678
+ data-filename="${a.filename}"
855
679
  @click=${() => this.showArtifact(a.filename)}
856
680
  >
857
681
  <span class="font-mono text-xs">${a.filename}</span>