@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,57 +1,410 @@
1
- import { Button, icon } from "@mariozechner/mini-lit";
1
+ import { Button, icon, Input } from "@mariozechner/mini-lit";
2
2
  import "@mariozechner/mini-lit/dist/ThemeToggle.js";
3
- import { ApiKeyPromptDialog, ApiKeysTab, ChatPanel, initAppStorage, ProxyTab, SettingsDialog } from "@mariozechner/pi-web-ui";
3
+ import { getModel } from "@mariozechner/pi-ai";
4
+ import {
5
+ Agent,
6
+ type AgentState,
7
+ ApiKeyPromptDialog,
8
+ ApiKeysTab,
9
+ type AppMessage,
10
+ AppStorage,
11
+ ChatPanel,
12
+ createJavaScriptReplTool,
13
+ IndexedDBStorageBackend,
14
+ // PersistentStorageDialog, // TODO: Fix - currently broken
15
+ ProviderKeysStore,
16
+ ProviderTransport,
17
+ ProxyTab,
18
+ SessionListDialog,
19
+ SessionsStore,
20
+ setAppStorage,
21
+ SettingsDialog,
22
+ SettingsStore,
23
+ } from "@mariozechner/pi-web-ui";
4
24
  import { html, render } from "lit";
5
- import { Settings } from "lucide";
25
+ import { Bell, History, Plus, Settings } from "lucide";
6
26
  import "./app.css";
27
+ import { createSystemNotification, customMessageTransformer, registerCustomMessageRenderers } from "./custom-messages.js";
7
28
 
8
- // Initialize storage with default configuration (localStorage)
9
- initAppStorage();
29
+ // Register custom message renderers
30
+ registerCustomMessageRenderers();
10
31
 
11
- const systemPrompt = `You are a helpful AI assistant with access to various tools.
32
+ // Create stores
33
+ const settings = new SettingsStore();
34
+ const providerKeys = new ProviderKeysStore();
35
+ const sessions = new SessionsStore();
36
+
37
+ // Gather configs
38
+ const configs = [settings.getConfig(), SessionsStore.getMetadataConfig(), providerKeys.getConfig(), sessions.getConfig()];
39
+
40
+ // Create backend
41
+ const backend = new IndexedDBStorageBackend({
42
+ dbName: "pi-web-ui-example",
43
+ version: 1,
44
+ stores: configs,
45
+ });
46
+
47
+ // Wire backend to stores
48
+ settings.setBackend(backend);
49
+ providerKeys.setBackend(backend);
50
+ sessions.setBackend(backend);
51
+
52
+ // Create and set app storage
53
+ const storage = new AppStorage(settings, providerKeys, sessions, backend);
54
+ setAppStorage(storage);
55
+
56
+ let currentSessionId: string | undefined;
57
+ let currentTitle = "";
58
+ let isEditingTitle = false;
59
+ let agent: Agent;
60
+ let chatPanel: ChatPanel;
61
+ let agentUnsubscribe: (() => void) | undefined;
62
+
63
+ const generateTitle = (messages: AppMessage[]): string => {
64
+ const firstUserMsg = messages.find((m) => m.role === "user");
65
+ if (!firstUserMsg || firstUserMsg.role !== "user") return "";
66
+
67
+ let text = "";
68
+ const content = firstUserMsg.content;
69
+
70
+ if (typeof content === "string") {
71
+ text = content;
72
+ } else {
73
+ const textBlocks = content.filter((c: any) => c.type === "text");
74
+ text = textBlocks.map((c: any) => c.text || "").join(" ");
75
+ }
76
+
77
+ text = text.trim();
78
+ if (!text) return "";
79
+
80
+ const sentenceEnd = text.search(/[.!?]/);
81
+ if (sentenceEnd > 0 && sentenceEnd <= 50) {
82
+ return text.substring(0, sentenceEnd + 1);
83
+ }
84
+ return text.length <= 50 ? text : text.substring(0, 47) + "...";
85
+ };
86
+
87
+ const shouldSaveSession = (messages: AppMessage[]): boolean => {
88
+ const hasUserMsg = messages.some((m: any) => m.role === "user");
89
+ const hasAssistantMsg = messages.some((m: any) => m.role === "assistant");
90
+ return hasUserMsg && hasAssistantMsg;
91
+ };
92
+
93
+ const saveSession = async () => {
94
+ if (!storage.sessions || !currentSessionId || !agent || !currentTitle) return;
95
+
96
+ const state = agent.state;
97
+ if (!shouldSaveSession(state.messages)) return;
98
+
99
+ try {
100
+ // Create session data
101
+ const sessionData = {
102
+ id: currentSessionId,
103
+ title: currentTitle,
104
+ model: state.model!,
105
+ thinkingLevel: state.thinkingLevel,
106
+ messages: state.messages,
107
+ createdAt: new Date().toISOString(),
108
+ lastModified: new Date().toISOString(),
109
+ };
110
+
111
+ // Create session metadata
112
+ const metadata = {
113
+ id: currentSessionId,
114
+ title: currentTitle,
115
+ createdAt: sessionData.createdAt,
116
+ lastModified: sessionData.lastModified,
117
+ messageCount: state.messages.length,
118
+ usage: {
119
+ input: 0,
120
+ output: 0,
121
+ cacheRead: 0,
122
+ cacheWrite: 0,
123
+ cost: {
124
+ input: 0,
125
+ output: 0,
126
+ cacheRead: 0,
127
+ cacheWrite: 0,
128
+ total: 0,
129
+ },
130
+ },
131
+ modelId: state.model?.id || null,
132
+ thinkingLevel: state.thinkingLevel,
133
+ preview: generateTitle(state.messages),
134
+ };
135
+
136
+ await storage.sessions.save(sessionData, metadata);
137
+ } catch (err) {
138
+ console.error("Failed to save session:", err);
139
+ }
140
+ };
141
+
142
+ const updateUrl = (sessionId: string) => {
143
+ const url = new URL(window.location.href);
144
+ url.searchParams.set("session", sessionId);
145
+ window.history.replaceState({}, "", url);
146
+ };
147
+
148
+ const createAgent = async (initialState?: Partial<AgentState>) => {
149
+ if (agentUnsubscribe) {
150
+ agentUnsubscribe();
151
+ }
152
+
153
+ const transport = new ProviderTransport();
154
+
155
+ agent = new Agent({
156
+ initialState: initialState || {
157
+ systemPrompt: `You are a helpful AI assistant with access to various tools.
12
158
 
13
159
  Available tools:
14
160
  - JavaScript REPL: Execute JavaScript code in a sandboxed browser environment (can do calculations, get time, process data, create visualizations, etc.)
15
161
  - Artifacts: Create interactive HTML, SVG, Markdown, and text artifacts
16
162
 
17
- Feel free to use these tools when needed to provide accurate and helpful responses.`;
163
+ Feel free to use these tools when needed to provide accurate and helpful responses.`,
164
+ model: getModel("anthropic", "claude-sonnet-4-5-20250929"),
165
+ thinkingLevel: "off",
166
+ messages: [],
167
+ tools: [],
168
+ },
169
+ transport,
170
+ // Custom transformer: convert system notifications to user messages with <system> tags
171
+ messageTransformer: customMessageTransformer,
172
+ });
173
+
174
+ agentUnsubscribe = agent.subscribe((event: any) => {
175
+ if (event.type === "state-update") {
176
+ const messages = event.state.messages;
18
177
 
19
- // Create and configure the chat panel
20
- const chatPanel = new ChatPanel();
21
- chatPanel.systemPrompt = systemPrompt;
22
- chatPanel.additionalTools = [];
23
- chatPanel.onApiKeyRequired = async (provider: string) => {
24
- return await ApiKeyPromptDialog.prompt(provider);
178
+ // Generate title after first successful response
179
+ if (!currentTitle && shouldSaveSession(messages)) {
180
+ currentTitle = generateTitle(messages);
181
+ }
182
+
183
+ // Create session ID on first successful save
184
+ if (!currentSessionId && shouldSaveSession(messages)) {
185
+ currentSessionId = crypto.randomUUID();
186
+ updateUrl(currentSessionId);
187
+ }
188
+
189
+ // Auto-save
190
+ if (currentSessionId) {
191
+ saveSession();
192
+ }
193
+
194
+ renderApp();
195
+ }
196
+ });
197
+
198
+ await chatPanel.setAgent(agent, {
199
+ onApiKeyRequired: async (provider: string) => {
200
+ return await ApiKeyPromptDialog.prompt(provider);
201
+ },
202
+ toolsFactory: (agent, agentInterface, artifactsPanel, runtimeProvidersFactory) => {
203
+ // Create javascript_repl tool with access to attachments + artifacts
204
+ const replTool = createJavaScriptReplTool();
205
+ replTool.runtimeProvidersFactory = runtimeProvidersFactory;
206
+ return [replTool];
207
+ }
208
+ });
25
209
  };
26
210
 
27
- // Render the app structure
28
- const appHtml = html`
29
- <div class="w-full h-screen flex flex-col bg-background text-foreground overflow-hidden">
30
- <!-- Header -->
31
- <div class="flex items-center justify-between border-b border-border shrink-0">
32
- <div class="px-4 py-3">
33
- <span class="text-base font-semibold text-foreground">Pi Web UI Example</span>
34
- </div>
35
- <div class="flex items-center gap-1 px-2">
36
- <theme-toggle></theme-toggle>
37
- ${Button({
38
- variant: "ghost",
39
- size: "sm",
40
- children: icon(Settings, "sm"),
41
- onClick: () => SettingsDialog.open([new ApiKeysTab(), new ProxyTab()]),
42
- title: "Settings",
43
- })}
211
+ const loadSession = async (sessionId: string): Promise<boolean> => {
212
+ if (!storage.sessions) return false;
213
+
214
+ const sessionData = await storage.sessions.get(sessionId);
215
+ if (!sessionData) {
216
+ console.error("Session not found:", sessionId);
217
+ return false;
218
+ }
219
+
220
+ currentSessionId = sessionId;
221
+ const metadata = await storage.sessions.getMetadata(sessionId);
222
+ currentTitle = metadata?.title || "";
223
+
224
+ await createAgent({
225
+ model: sessionData.model,
226
+ thinkingLevel: sessionData.thinkingLevel,
227
+ messages: sessionData.messages,
228
+ tools: [],
229
+ });
230
+
231
+ updateUrl(sessionId);
232
+ renderApp();
233
+ return true;
234
+ };
235
+
236
+ const newSession = () => {
237
+ const url = new URL(window.location.href);
238
+ url.search = "";
239
+ window.location.href = url.toString();
240
+ };
241
+
242
+ // ============================================================================
243
+ // RENDER
244
+ // ============================================================================
245
+ const renderApp = () => {
246
+ const app = document.getElementById("app");
247
+ if (!app) return;
248
+
249
+ const appHtml = html`
250
+ <div class="w-full h-screen flex flex-col bg-background text-foreground overflow-hidden">
251
+ <!-- Header -->
252
+ <div class="flex items-center justify-between border-b border-border shrink-0">
253
+ <div class="flex items-center gap-2 px-4 py-">
254
+ ${Button({
255
+ variant: "ghost",
256
+ size: "sm",
257
+ children: icon(History, "sm"),
258
+ onClick: () => {
259
+ SessionListDialog.open(
260
+ async (sessionId) => {
261
+ await loadSession(sessionId);
262
+ },
263
+ (deletedSessionId) => {
264
+ // Only reload if the current session was deleted
265
+ if (deletedSessionId === currentSessionId) {
266
+ newSession();
267
+ }
268
+ },
269
+ );
270
+ },
271
+ title: "Sessions",
272
+ })}
273
+ ${Button({
274
+ variant: "ghost",
275
+ size: "sm",
276
+ children: icon(Plus, "sm"),
277
+ onClick: newSession,
278
+ title: "New Session",
279
+ })}
280
+
281
+ ${currentTitle
282
+ ? isEditingTitle
283
+ ? html`<div class="flex items-center gap-2">
284
+ ${Input({
285
+ type: "text",
286
+ value: currentTitle,
287
+ className: "text-sm w-64",
288
+ onChange: async (e: Event) => {
289
+ const newTitle = (e.target as HTMLInputElement).value.trim();
290
+ if (newTitle && newTitle !== currentTitle && storage.sessions && currentSessionId) {
291
+ await storage.sessions.updateTitle(currentSessionId, newTitle);
292
+ currentTitle = newTitle;
293
+ }
294
+ isEditingTitle = false;
295
+ renderApp();
296
+ },
297
+ onKeyDown: async (e: KeyboardEvent) => {
298
+ if (e.key === "Enter") {
299
+ const newTitle = (e.target as HTMLInputElement).value.trim();
300
+ if (newTitle && newTitle !== currentTitle && storage.sessions && currentSessionId) {
301
+ await storage.sessions.updateTitle(currentSessionId, newTitle);
302
+ currentTitle = newTitle;
303
+ }
304
+ isEditingTitle = false;
305
+ renderApp();
306
+ } else if (e.key === "Escape") {
307
+ isEditingTitle = false;
308
+ renderApp();
309
+ }
310
+ },
311
+ })}
312
+ </div>`
313
+ : html`<button
314
+ class="px-2 py-1 text-sm text-foreground hover:bg-secondary rounded transition-colors"
315
+ @click=${() => {
316
+ isEditingTitle = true;
317
+ renderApp();
318
+ requestAnimationFrame(() => {
319
+ const input = app?.querySelector('input[type="text"]') as HTMLInputElement;
320
+ if (input) {
321
+ input.focus();
322
+ input.select();
323
+ }
324
+ });
325
+ }}
326
+ title="Click to edit title"
327
+ >
328
+ ${currentTitle}
329
+ </button>`
330
+ : html`<span class="text-base font-semibold text-foreground">Pi Web UI Example</span>`}
331
+ </div>
332
+ <div class="flex items-center gap-1 px-2">
333
+ ${Button({
334
+ variant: "ghost",
335
+ size: "sm",
336
+ children: icon(Bell, "sm"),
337
+ onClick: () => {
338
+ // Demo: Inject custom message
339
+ if (agent) {
340
+ agent.appendMessage(
341
+ createSystemNotification("This is a custom message! It appears in the UI but is never sent to the LLM."),
342
+ );
343
+ }
344
+ },
345
+ title: "Demo: Add Custom Notification",
346
+ })}
347
+ <theme-toggle></theme-toggle>
348
+ ${Button({
349
+ variant: "ghost",
350
+ size: "sm",
351
+ children: icon(Settings, "sm"),
352
+ onClick: () => SettingsDialog.open([new ApiKeysTab(), new ProxyTab()]),
353
+ title: "Settings",
354
+ })}
355
+ </div>
44
356
  </div>
357
+
358
+ <!-- Chat Panel -->
359
+ ${chatPanel}
45
360
  </div>
361
+ `;
362
+
363
+ render(appHtml, app);
364
+ };
365
+
366
+ // ============================================================================
367
+ // INIT
368
+ // ============================================================================
369
+ async function initApp() {
370
+ const app = document.getElementById("app");
371
+ if (!app) throw new Error("App container not found");
372
+
373
+ // Show loading
374
+ render(
375
+ html`
376
+ <div class="w-full h-screen flex items-center justify-center bg-background text-foreground">
377
+ <div class="text-muted-foreground">Loading...</div>
378
+ </div>
379
+ `,
380
+ app,
381
+ );
382
+
383
+ // TODO: Fix PersistentStorageDialog - currently broken
384
+ // Request persistent storage
385
+ // if (storage.sessions) {
386
+ // await PersistentStorageDialog.request();
387
+ // }
388
+
389
+ // Create ChatPanel
390
+ chatPanel = new ChatPanel();
391
+
392
+ // Check for session in URL
393
+ const urlParams = new URLSearchParams(window.location.search);
394
+ const sessionIdFromUrl = urlParams.get("session");
46
395
 
47
- <!-- Chat Panel -->
48
- ${chatPanel}
49
- </div>
50
- `;
396
+ if (sessionIdFromUrl) {
397
+ const loaded = await loadSession(sessionIdFromUrl);
398
+ if (!loaded) {
399
+ // Session doesn't exist, redirect to new session
400
+ newSession();
401
+ return;
402
+ }
403
+ } else {
404
+ await createAgent();
405
+ }
51
406
 
52
- const app = document.getElementById("app");
53
- if (!app) {
54
- throw new Error("App container not found");
407
+ renderApp();
55
408
  }
56
409
 
57
- render(appHtml, app);
410
+ initApp();
package/package.json CHANGED
@@ -1,45 +1,50 @@
1
1
  {
2
- "name": "@mariozechner/pi-web-ui",
3
- "version": "0.5.44",
4
- "description": "Reusable web UI components for AI chat interfaces powered by @mariozechner/pi-ai",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": "./dist/index.js",
10
- "./app.css": "./dist/app.css"
11
- },
12
- "scripts": {
13
- "clean": "rm -rf dist",
14
- "build": "tsc -p tsconfig.build.json && tailwindcss -i ./src/app.css -o ./dist/app.css --minify",
15
- "dev": "concurrently --names \"build,example\" --prefix-colors \"cyan,green\" \"tsc -p tsconfig.build.json --watch\" \"tailwindcss -i ./src/app.css -o ./dist/app.css --watch\" \"npm run dev --prefix example\"",
16
- "typecheck": "tsc --noEmit",
17
- "check": "npm run typecheck"
18
- },
19
- "dependencies": {
20
- "@mariozechner/mini-lit": "^0.1.8",
21
- "@mariozechner/pi-ai": "^0.5.43",
22
- "docx-preview": "^0.3.7",
23
- "jszip": "^3.10.1",
24
- "lit": "^3.3.1",
25
- "lucide": "^0.544.0",
26
- "pdfjs-dist": "^5.4.149",
27
- "xlsx": "^0.18.5"
28
- },
29
- "devDependencies": {
30
- "@tailwindcss/cli": "^4.0.0-beta.14",
31
- "concurrently": "^9.2.1",
32
- "typescript": "^5.7.3"
33
- },
34
- "keywords": [
35
- "ai",
36
- "chat",
37
- "ui",
38
- "components",
39
- "llm",
40
- "web-components",
41
- "mini-lit"
42
- ],
43
- "author": "Mario Zechner",
44
- "license": "MIT"
2
+ "name": "@mariozechner/pi-web-ui",
3
+ "version": "0.5.46",
4
+ "description": "Reusable web UI components for AI chat interfaces powered by @mariozechner/pi-ai",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./app.css": "./dist/app.css"
11
+ },
12
+ "scripts": {
13
+ "clean": "rm -rf dist",
14
+ "build": "tsc -p tsconfig.build.json && tailwindcss -i ./src/app.css -o ./dist/app.css --minify",
15
+ "dev": "concurrently --names \"build,example\" --prefix-colors \"cyan,green\" \"tsc -p tsconfig.build.json --watch --preserveWatchOutput\" \"tailwindcss -i ./src/app.css -o ./dist/app.css --watch\" \"npm run dev --prefix example\"",
16
+ "typecheck": "tsc --noEmit && cd example && tsc --noEmit",
17
+ "check": "npm run typecheck"
18
+ },
19
+ "dependencies": {
20
+ "@mariozechner/pi-ai": "^0.5.43",
21
+ "@mariozechner/pi-tui": "^0.5.46",
22
+ "docx-preview": "^0.3.7",
23
+ "jszip": "^3.10.1",
24
+ "lit": "^3.3.1",
25
+ "lucide": "^0.544.0",
26
+ "ollama": "^0.6.0",
27
+ "pdfjs-dist": "^5.4.296",
28
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
29
+ },
30
+ "peerDependencies": {
31
+ "@mariozechner/mini-lit": "^0.1.10"
32
+ },
33
+ "devDependencies": {
34
+ "@mariozechner/mini-lit": "^0.1.10",
35
+ "@tailwindcss/cli": "^4.0.0-beta.14",
36
+ "concurrently": "^9.2.1",
37
+ "typescript": "^5.7.3"
38
+ },
39
+ "keywords": [
40
+ "ai",
41
+ "chat",
42
+ "ui",
43
+ "components",
44
+ "llm",
45
+ "web-components",
46
+ "mini-lit"
47
+ ],
48
+ "author": "Mario Zechner",
49
+ "license": "MIT"
45
50
  }
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Count tokens in system prompts using Anthropic's token counter API
4
+ */
5
+
6
+ import * as prompts from "../src/prompts/prompts.js";
7
+
8
+ const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
9
+
10
+ if (!ANTHROPIC_API_KEY) {
11
+ console.error("Error: ANTHROPIC_API_KEY environment variable not set");
12
+ process.exit(1);
13
+ }
14
+
15
+ interface TokenCountResponse {
16
+ input_tokens: number;
17
+ }
18
+
19
+ async function countTokens(text: string): Promise<number> {
20
+ const response = await fetch("https://api.anthropic.com/v1/messages/count_tokens", {
21
+ method: "POST",
22
+ headers: {
23
+ "Content-Type": "application/json",
24
+ "x-api-key": ANTHROPIC_API_KEY,
25
+ "anthropic-version": "2023-06-01",
26
+ },
27
+ body: JSON.stringify({
28
+ model: "claude-3-5-sonnet-20241022",
29
+ messages: [
30
+ {
31
+ role: "user",
32
+ content: text,
33
+ },
34
+ ],
35
+ }),
36
+ });
37
+
38
+ if (!response.ok) {
39
+ const error = await response.text();
40
+ throw new Error(`API error: ${response.status} ${error}`);
41
+ }
42
+
43
+ const data = (await response.json()) as TokenCountResponse;
44
+ return data.input_tokens;
45
+ }
46
+
47
+ async function main() {
48
+ console.log("Counting tokens in prompts...\n");
49
+
50
+ const promptsToCount: Array<{ name: string; content: string }> = [
51
+ {
52
+ name: "ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW",
53
+ content: prompts.ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW,
54
+ },
55
+ {
56
+ name: "ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO",
57
+ content: prompts.ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO,
58
+ },
59
+ {
60
+ name: "ATTACHMENTS_RUNTIME_DESCRIPTION",
61
+ content: prompts.ATTACHMENTS_RUNTIME_DESCRIPTION,
62
+ },
63
+ {
64
+ name: "JAVASCRIPT_REPL_TOOL_DESCRIPTION (without runtime providers)",
65
+ content: prompts.JAVASCRIPT_REPL_TOOL_DESCRIPTION([]),
66
+ },
67
+ {
68
+ name: "ARTIFACTS_TOOL_DESCRIPTION (without runtime providers)",
69
+ content: prompts.ARTIFACTS_TOOL_DESCRIPTION([]),
70
+ },
71
+ ];
72
+
73
+ let total = 0;
74
+
75
+ for (const prompt of promptsToCount) {
76
+ try {
77
+ const tokens = await countTokens(prompt.content);
78
+ total += tokens;
79
+ console.log(`${prompt.name}: ${tokens.toLocaleString()} tokens`);
80
+ } catch (error) {
81
+ console.error(`Error counting tokens for ${prompt.name}:`, error);
82
+ }
83
+ }
84
+
85
+ console.log(`\nTotal: ${total.toLocaleString()} tokens`);
86
+ }
87
+
88
+ main();