@buoy-gg/ask-buoy 7.0.36 → 7.0.38

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 (312) hide show
  1. package/README.md +58 -27
  2. package/lib/commonjs/blocks/AskBlocks.js +1 -338
  3. package/lib/commonjs/blocks/BlockRenderer.js +1 -262
  4. package/lib/commonjs/blocks/ChromePrototypes.js +1 -514
  5. package/lib/commonjs/blocks/DataBlocks.js +1 -781
  6. package/lib/commonjs/blocks/ExtraBlocks.js +1 -1860
  7. package/lib/commonjs/blocks/MediaBlocks.js +1 -156
  8. package/lib/commonjs/blocks/ReceiptBlocks.js +1 -586
  9. package/lib/commonjs/blocks/blockText.js +1 -60
  10. package/lib/commonjs/blocks/blockText.test.js +1 -53
  11. package/lib/commonjs/blocks/context.js +1 -42
  12. package/lib/commonjs/blocks/icons.js +1 -96
  13. package/lib/commonjs/blocks/index.js +1 -95
  14. package/lib/commonjs/blocks/listRow.test.js +1 -55
  15. package/lib/commonjs/blocks/pageState.js +1 -34
  16. package/lib/commonjs/blocks/pageState.test.js +1 -57
  17. package/lib/commonjs/blocks/primitives.js +1 -457
  18. package/lib/commonjs/blocks/primitivesIndex.js +1 -62
  19. package/lib/commonjs/components/ApprovalCard.js +1 -244
  20. package/lib/commonjs/components/AskBuoyHeader.js +1 -196
  21. package/lib/commonjs/components/AskBuoyIcon.js +1 -19
  22. package/lib/commonjs/components/AskBuoyModal.js +1 -479
  23. package/lib/commonjs/components/AskBuoySettings.js +1 -119
  24. package/lib/commonjs/components/ChangesBar.js +1 -211
  25. package/lib/commonjs/components/Composer.js +1 -255
  26. package/lib/commonjs/components/EmptyState.js +1 -161
  27. package/lib/commonjs/components/KeyboardPad.js +1 -80
  28. package/lib/commonjs/components/Markdown.js +1 -310
  29. package/lib/commonjs/components/MessageList.js +1 -930
  30. package/lib/commonjs/components/QueuedMessages.js +1 -145
  31. package/lib/commonjs/components/ThinkingStrip.js +1 -223
  32. package/lib/commonjs/components/TypingDots.js +1 -63
  33. package/lib/commonjs/components/markdownParse.js +1 -131
  34. package/lib/commonjs/components/markdownParse.test.js +1 -99
  35. package/lib/commonjs/components/useCopyAction.js +1 -50
  36. package/lib/commonjs/index.js +1 -252
  37. package/lib/commonjs/preset.js +1 -90
  38. package/lib/commonjs/store/activityGroups.js +1 -110
  39. package/lib/commonjs/store/activityGroups.test.js +1 -78
  40. package/lib/commonjs/store/askBuoySettings.js +1 -72
  41. package/lib/commonjs/store/askBuoyStore.js +1 -547
  42. package/lib/commonjs/store/blockPlacement.js +1 -64
  43. package/lib/commonjs/store/blockPlacement.test.js +1 -123
  44. package/lib/commonjs/store/queue.test.js +1 -150
  45. package/lib/commonjs/store/resetConversation.js +1 -77
  46. package/lib/commonjs/store/restorePending.test.js +1 -63
  47. package/lib/commonjs/store/restoredIds.test.js +1 -47
  48. package/lib/commonjs/store/suggestions.js +1 -54
  49. package/lib/commonjs/store/suggestions.test.js +1 -58
  50. package/lib/commonjs/store/systemLine.test.js +1 -77
  51. package/lib/commonjs/store/ticketPrompt.js +1 -17
  52. package/lib/commonjs/store/traceText.js +1 -81
  53. package/lib/commonjs/store/traceText.test.js +1 -112
  54. package/lib/commonjs/store/transcriptPersistence.js +1 -297
  55. package/lib/commonjs/store/transcriptPersistence.test.js +1 -333
  56. package/lib/commonjs/store/turnRendering.test.js +1 -151
  57. package/lib/commonjs/store/useAskBuoy.js +1 -622
  58. package/lib/commonjs/store/useAskBuoySettings.js +1 -14
  59. package/lib/commonjs/sync/askBuoySyncAdapter.js +1 -140
  60. package/lib/commonjs/sync/askBuoySyncAdapter.test.js +1 -141
  61. package/lib/commonjs/sync/wire.js +1 -58
  62. package/lib/commonjs/types.js +1 -6
  63. package/lib/module/blocks/AskBlocks.js +1 -331
  64. package/lib/module/blocks/BlockRenderer.js +1 -257
  65. package/lib/module/blocks/ChromePrototypes.js +1 -503
  66. package/lib/module/blocks/DataBlocks.js +1 -767
  67. package/lib/module/blocks/ExtraBlocks.js +1 -1833
  68. package/lib/module/blocks/MediaBlocks.js +1 -151
  69. package/lib/module/blocks/ReceiptBlocks.js +1 -574
  70. package/lib/module/blocks/blockText.js +1 -55
  71. package/lib/module/blocks/blockText.test.js +1 -53
  72. package/lib/module/blocks/context.js +1 -35
  73. package/lib/module/blocks/icons.js +1 -91
  74. package/lib/module/blocks/index.js +1 -8
  75. package/lib/module/blocks/listRow.test.js +1 -56
  76. package/lib/module/blocks/pageState.js +1 -30
  77. package/lib/module/blocks/pageState.test.js +1 -56
  78. package/lib/module/blocks/primitives.js +1 -445
  79. package/lib/module/blocks/primitivesIndex.js +1 -5
  80. package/lib/module/components/ApprovalCard.js +1 -239
  81. package/lib/module/components/AskBuoyHeader.js +1 -193
  82. package/lib/module/components/AskBuoyIcon.js +1 -8
  83. package/lib/module/components/AskBuoyModal.js +1 -474
  84. package/lib/module/components/AskBuoySettings.js +1 -114
  85. package/lib/module/components/ChangesBar.js +1 -206
  86. package/lib/module/components/Composer.js +1 -250
  87. package/lib/module/components/EmptyState.js +1 -156
  88. package/lib/module/components/KeyboardPad.js +1 -75
  89. package/lib/module/components/Markdown.js +1 -305
  90. package/lib/module/components/MessageList.js +1 -924
  91. package/lib/module/components/QueuedMessages.js +1 -140
  92. package/lib/module/components/ThinkingStrip.js +1 -218
  93. package/lib/module/components/TypingDots.js +1 -58
  94. package/lib/module/components/markdownParse.js +1 -125
  95. package/lib/module/components/markdownParse.test.js +1 -98
  96. package/lib/module/components/useCopyAction.js +1 -46
  97. package/lib/module/index.js +1 -34
  98. package/lib/module/preset.js +1 -73
  99. package/lib/module/store/activityGroups.js +1 -103
  100. package/lib/module/store/activityGroups.test.js +1 -77
  101. package/lib/module/store/askBuoySettings.js +1 -67
  102. package/lib/module/store/askBuoyStore.js +1 -541
  103. package/lib/module/store/blockPlacement.js +1 -59
  104. package/lib/module/store/blockPlacement.test.js +1 -122
  105. package/lib/module/store/queue.test.js +1 -149
  106. package/lib/module/store/resetConversation.js +1 -72
  107. package/lib/module/store/restorePending.test.js +1 -62
  108. package/lib/module/store/restoredIds.test.js +1 -46
  109. package/lib/module/store/suggestions.js +1 -49
  110. package/lib/module/store/suggestions.test.js +1 -57
  111. package/lib/module/store/systemLine.test.js +1 -76
  112. package/lib/module/store/ticketPrompt.js +1 -13
  113. package/lib/module/store/traceText.js +1 -75
  114. package/lib/module/store/traceText.test.js +1 -111
  115. package/lib/module/store/transcriptPersistence.js +1 -287
  116. package/lib/module/store/transcriptPersistence.test.js +1 -332
  117. package/lib/module/store/turnRendering.test.js +1 -150
  118. package/lib/module/store/useAskBuoy.js +1 -616
  119. package/lib/module/store/useAskBuoySettings.js +1 -9
  120. package/lib/module/sync/askBuoySyncAdapter.js +1 -135
  121. package/lib/module/sync/askBuoySyncAdapter.test.js +1 -140
  122. package/lib/module/sync/wire.js +1 -47
  123. package/lib/module/types.js +1 -4
  124. package/lib/typescript/components/ApprovalCard.d.ts +9 -1
  125. package/lib/typescript/preset.d.ts +4 -2
  126. package/lib/typescript/store/askBuoyStore.d.ts +32 -4
  127. package/lib/typescript/store/useAskBuoy.d.ts +3 -2
  128. package/lib/typescript/sync/askBuoySyncAdapter.d.ts +3 -0
  129. package/package.json +9 -9
  130. package/lib/commonjs/blocks/AskBlocks.js.map +0 -1
  131. package/lib/commonjs/blocks/BlockRenderer.js.map +0 -1
  132. package/lib/commonjs/blocks/ChromePrototypes.js.map +0 -1
  133. package/lib/commonjs/blocks/DataBlocks.js.map +0 -1
  134. package/lib/commonjs/blocks/ExtraBlocks.js.map +0 -1
  135. package/lib/commonjs/blocks/MediaBlocks.js.map +0 -1
  136. package/lib/commonjs/blocks/ReceiptBlocks.js.map +0 -1
  137. package/lib/commonjs/blocks/blockText.js.map +0 -1
  138. package/lib/commonjs/blocks/blockText.test.js.map +0 -1
  139. package/lib/commonjs/blocks/context.js.map +0 -1
  140. package/lib/commonjs/blocks/icons.js.map +0 -1
  141. package/lib/commonjs/blocks/index.js.map +0 -1
  142. package/lib/commonjs/blocks/listRow.test.js.map +0 -1
  143. package/lib/commonjs/blocks/pageState.js.map +0 -1
  144. package/lib/commonjs/blocks/pageState.test.js.map +0 -1
  145. package/lib/commonjs/blocks/primitives.js.map +0 -1
  146. package/lib/commonjs/blocks/primitivesIndex.js.map +0 -1
  147. package/lib/commonjs/components/ApprovalCard.js.map +0 -1
  148. package/lib/commonjs/components/AskBuoyHeader.js.map +0 -1
  149. package/lib/commonjs/components/AskBuoyIcon.js.map +0 -1
  150. package/lib/commonjs/components/AskBuoyModal.js.map +0 -1
  151. package/lib/commonjs/components/AskBuoySettings.js.map +0 -1
  152. package/lib/commonjs/components/ChangesBar.js.map +0 -1
  153. package/lib/commonjs/components/Composer.js.map +0 -1
  154. package/lib/commonjs/components/EmptyState.js.map +0 -1
  155. package/lib/commonjs/components/KeyboardPad.js.map +0 -1
  156. package/lib/commonjs/components/Markdown.js.map +0 -1
  157. package/lib/commonjs/components/MessageList.js.map +0 -1
  158. package/lib/commonjs/components/QueuedMessages.js.map +0 -1
  159. package/lib/commonjs/components/ThinkingStrip.js.map +0 -1
  160. package/lib/commonjs/components/TypingDots.js.map +0 -1
  161. package/lib/commonjs/components/markdownParse.js.map +0 -1
  162. package/lib/commonjs/components/markdownParse.test.js.map +0 -1
  163. package/lib/commonjs/components/useCopyAction.js.map +0 -1
  164. package/lib/commonjs/index.js.map +0 -1
  165. package/lib/commonjs/preset.js.map +0 -1
  166. package/lib/commonjs/store/activityGroups.js.map +0 -1
  167. package/lib/commonjs/store/activityGroups.test.js.map +0 -1
  168. package/lib/commonjs/store/askBuoySettings.js.map +0 -1
  169. package/lib/commonjs/store/askBuoyStore.js.map +0 -1
  170. package/lib/commonjs/store/blockPlacement.js.map +0 -1
  171. package/lib/commonjs/store/blockPlacement.test.js.map +0 -1
  172. package/lib/commonjs/store/queue.test.js.map +0 -1
  173. package/lib/commonjs/store/resetConversation.js.map +0 -1
  174. package/lib/commonjs/store/restorePending.test.js.map +0 -1
  175. package/lib/commonjs/store/restoredIds.test.js.map +0 -1
  176. package/lib/commonjs/store/suggestions.js.map +0 -1
  177. package/lib/commonjs/store/suggestions.test.js.map +0 -1
  178. package/lib/commonjs/store/systemLine.test.js.map +0 -1
  179. package/lib/commonjs/store/ticketPrompt.js.map +0 -1
  180. package/lib/commonjs/store/traceText.js.map +0 -1
  181. package/lib/commonjs/store/traceText.test.js.map +0 -1
  182. package/lib/commonjs/store/transcriptPersistence.js.map +0 -1
  183. package/lib/commonjs/store/transcriptPersistence.test.js.map +0 -1
  184. package/lib/commonjs/store/turnRendering.test.js.map +0 -1
  185. package/lib/commonjs/store/useAskBuoy.js.map +0 -1
  186. package/lib/commonjs/store/useAskBuoySettings.js.map +0 -1
  187. package/lib/commonjs/sync/askBuoySyncAdapter.js.map +0 -1
  188. package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +0 -1
  189. package/lib/commonjs/sync/wire.js.map +0 -1
  190. package/lib/commonjs/types.js.map +0 -1
  191. package/lib/module/blocks/AskBlocks.js.map +0 -1
  192. package/lib/module/blocks/BlockRenderer.js.map +0 -1
  193. package/lib/module/blocks/ChromePrototypes.js.map +0 -1
  194. package/lib/module/blocks/DataBlocks.js.map +0 -1
  195. package/lib/module/blocks/ExtraBlocks.js.map +0 -1
  196. package/lib/module/blocks/MediaBlocks.js.map +0 -1
  197. package/lib/module/blocks/ReceiptBlocks.js.map +0 -1
  198. package/lib/module/blocks/blockText.js.map +0 -1
  199. package/lib/module/blocks/blockText.test.js.map +0 -1
  200. package/lib/module/blocks/context.js.map +0 -1
  201. package/lib/module/blocks/icons.js.map +0 -1
  202. package/lib/module/blocks/index.js.map +0 -1
  203. package/lib/module/blocks/listRow.test.js.map +0 -1
  204. package/lib/module/blocks/pageState.js.map +0 -1
  205. package/lib/module/blocks/pageState.test.js.map +0 -1
  206. package/lib/module/blocks/primitives.js.map +0 -1
  207. package/lib/module/blocks/primitivesIndex.js.map +0 -1
  208. package/lib/module/components/ApprovalCard.js.map +0 -1
  209. package/lib/module/components/AskBuoyHeader.js.map +0 -1
  210. package/lib/module/components/AskBuoyIcon.js.map +0 -1
  211. package/lib/module/components/AskBuoyModal.js.map +0 -1
  212. package/lib/module/components/AskBuoySettings.js.map +0 -1
  213. package/lib/module/components/ChangesBar.js.map +0 -1
  214. package/lib/module/components/Composer.js.map +0 -1
  215. package/lib/module/components/EmptyState.js.map +0 -1
  216. package/lib/module/components/KeyboardPad.js.map +0 -1
  217. package/lib/module/components/Markdown.js.map +0 -1
  218. package/lib/module/components/MessageList.js.map +0 -1
  219. package/lib/module/components/QueuedMessages.js.map +0 -1
  220. package/lib/module/components/ThinkingStrip.js.map +0 -1
  221. package/lib/module/components/TypingDots.js.map +0 -1
  222. package/lib/module/components/markdownParse.js.map +0 -1
  223. package/lib/module/components/markdownParse.test.js.map +0 -1
  224. package/lib/module/components/useCopyAction.js.map +0 -1
  225. package/lib/module/index.js.map +0 -1
  226. package/lib/module/preset.js.map +0 -1
  227. package/lib/module/store/activityGroups.js.map +0 -1
  228. package/lib/module/store/activityGroups.test.js.map +0 -1
  229. package/lib/module/store/askBuoySettings.js.map +0 -1
  230. package/lib/module/store/askBuoyStore.js.map +0 -1
  231. package/lib/module/store/blockPlacement.js.map +0 -1
  232. package/lib/module/store/blockPlacement.test.js.map +0 -1
  233. package/lib/module/store/queue.test.js.map +0 -1
  234. package/lib/module/store/resetConversation.js.map +0 -1
  235. package/lib/module/store/restorePending.test.js.map +0 -1
  236. package/lib/module/store/restoredIds.test.js.map +0 -1
  237. package/lib/module/store/suggestions.js.map +0 -1
  238. package/lib/module/store/suggestions.test.js.map +0 -1
  239. package/lib/module/store/systemLine.test.js.map +0 -1
  240. package/lib/module/store/ticketPrompt.js.map +0 -1
  241. package/lib/module/store/traceText.js.map +0 -1
  242. package/lib/module/store/traceText.test.js.map +0 -1
  243. package/lib/module/store/transcriptPersistence.js.map +0 -1
  244. package/lib/module/store/transcriptPersistence.test.js.map +0 -1
  245. package/lib/module/store/turnRendering.test.js.map +0 -1
  246. package/lib/module/store/useAskBuoy.js.map +0 -1
  247. package/lib/module/store/useAskBuoySettings.js.map +0 -1
  248. package/lib/module/sync/askBuoySyncAdapter.js.map +0 -1
  249. package/lib/module/sync/askBuoySyncAdapter.test.js.map +0 -1
  250. package/lib/module/sync/wire.js.map +0 -1
  251. package/lib/module/types.js.map +0 -1
  252. package/lib/typescript/blocks/AskBlocks.d.ts.map +0 -1
  253. package/lib/typescript/blocks/BlockRenderer.d.ts.map +0 -1
  254. package/lib/typescript/blocks/ChromePrototypes.d.ts.map +0 -1
  255. package/lib/typescript/blocks/DataBlocks.d.ts.map +0 -1
  256. package/lib/typescript/blocks/ExtraBlocks.d.ts.map +0 -1
  257. package/lib/typescript/blocks/MediaBlocks.d.ts.map +0 -1
  258. package/lib/typescript/blocks/ReceiptBlocks.d.ts.map +0 -1
  259. package/lib/typescript/blocks/blockText.d.ts.map +0 -1
  260. package/lib/typescript/blocks/blockText.test.d.ts.map +0 -1
  261. package/lib/typescript/blocks/context.d.ts.map +0 -1
  262. package/lib/typescript/blocks/icons.d.ts.map +0 -1
  263. package/lib/typescript/blocks/index.d.ts.map +0 -1
  264. package/lib/typescript/blocks/listRow.test.d.ts.map +0 -1
  265. package/lib/typescript/blocks/pageState.d.ts.map +0 -1
  266. package/lib/typescript/blocks/pageState.test.d.ts.map +0 -1
  267. package/lib/typescript/blocks/primitives.d.ts.map +0 -1
  268. package/lib/typescript/blocks/primitivesIndex.d.ts.map +0 -1
  269. package/lib/typescript/components/ApprovalCard.d.ts.map +0 -1
  270. package/lib/typescript/components/AskBuoyHeader.d.ts.map +0 -1
  271. package/lib/typescript/components/AskBuoyIcon.d.ts.map +0 -1
  272. package/lib/typescript/components/AskBuoyModal.d.ts.map +0 -1
  273. package/lib/typescript/components/AskBuoySettings.d.ts.map +0 -1
  274. package/lib/typescript/components/ChangesBar.d.ts.map +0 -1
  275. package/lib/typescript/components/Composer.d.ts.map +0 -1
  276. package/lib/typescript/components/EmptyState.d.ts.map +0 -1
  277. package/lib/typescript/components/KeyboardPad.d.ts.map +0 -1
  278. package/lib/typescript/components/Markdown.d.ts.map +0 -1
  279. package/lib/typescript/components/MessageList.d.ts.map +0 -1
  280. package/lib/typescript/components/QueuedMessages.d.ts.map +0 -1
  281. package/lib/typescript/components/ThinkingStrip.d.ts.map +0 -1
  282. package/lib/typescript/components/TypingDots.d.ts.map +0 -1
  283. package/lib/typescript/components/markdownParse.d.ts.map +0 -1
  284. package/lib/typescript/components/markdownParse.test.d.ts.map +0 -1
  285. package/lib/typescript/components/useCopyAction.d.ts.map +0 -1
  286. package/lib/typescript/index.d.ts.map +0 -1
  287. package/lib/typescript/preset.d.ts.map +0 -1
  288. package/lib/typescript/store/activityGroups.d.ts.map +0 -1
  289. package/lib/typescript/store/activityGroups.test.d.ts.map +0 -1
  290. package/lib/typescript/store/askBuoySettings.d.ts.map +0 -1
  291. package/lib/typescript/store/askBuoyStore.d.ts.map +0 -1
  292. package/lib/typescript/store/blockPlacement.d.ts.map +0 -1
  293. package/lib/typescript/store/blockPlacement.test.d.ts.map +0 -1
  294. package/lib/typescript/store/queue.test.d.ts.map +0 -1
  295. package/lib/typescript/store/resetConversation.d.ts.map +0 -1
  296. package/lib/typescript/store/restorePending.test.d.ts.map +0 -1
  297. package/lib/typescript/store/restoredIds.test.d.ts.map +0 -1
  298. package/lib/typescript/store/suggestions.d.ts.map +0 -1
  299. package/lib/typescript/store/suggestions.test.d.ts.map +0 -1
  300. package/lib/typescript/store/systemLine.test.d.ts.map +0 -1
  301. package/lib/typescript/store/ticketPrompt.d.ts.map +0 -1
  302. package/lib/typescript/store/traceText.d.ts.map +0 -1
  303. package/lib/typescript/store/traceText.test.d.ts.map +0 -1
  304. package/lib/typescript/store/transcriptPersistence.d.ts.map +0 -1
  305. package/lib/typescript/store/transcriptPersistence.test.d.ts.map +0 -1
  306. package/lib/typescript/store/turnRendering.test.d.ts.map +0 -1
  307. package/lib/typescript/store/useAskBuoy.d.ts.map +0 -1
  308. package/lib/typescript/store/useAskBuoySettings.d.ts.map +0 -1
  309. package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +0 -1
  310. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +0 -1
  311. package/lib/typescript/sync/wire.d.ts.map +0 -1
  312. package/lib/typescript/types.d.ts.map +0 -1
@@ -1,77 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _askBuoyStore = require("./askBuoyStore");
5
- var _transcriptPersistence = require("./transcriptPersistence");
6
- /**
7
- * Buoy's own lines in the transcript — today, the memory-trim notice.
8
- */
9
-
10
- (0, _vitest.beforeEach)(() => _askBuoyStore.askBuoyStore.reset());
11
- (0, _vitest.describe)("history-trimmed", () => {
12
- (0, _vitest.it)("inserts a system line before the answer it affects", () => {
13
- _askBuoyStore.askBuoyStore.addUser("turn off that override");
14
- const id = _askBuoyStore.askBuoyStore.startAssistant();
15
- _askBuoyStore.askBuoyStore.applyEvent(id, {
16
- type: "history-trimmed",
17
- droppedRounds: 3
18
- });
19
- _askBuoyStore.askBuoyStore.applyEvent(id, {
20
- type: "text",
21
- delta: "Turning it off."
22
- });
23
- const roles = _askBuoyStore.askBuoyStore.getState().messages.map(m => m.system ? "system" : m.role);
24
- (0, _vitest.expect)(roles).toEqual(["user", "system", "assistant"]);
25
- const line = _askBuoyStore.askBuoyStore.getState().messages[1];
26
- (0, _vitest.expect)(line.text).toMatch(/3 exchanges/);
27
- (0, _vitest.expect)(line.text).toMatch(/changes bar still lists/);
28
- });
29
- (0, _vitest.it)("singular for one round", () => {
30
- const id = _askBuoyStore.askBuoyStore.startAssistant();
31
- _askBuoyStore.askBuoyStore.applyEvent(id, {
32
- type: "history-trimmed",
33
- droppedRounds: 1
34
- });
35
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.getState().messages[0].text).toMatch(/1 exchange\)/);
36
- });
37
- });
38
- (0, _vitest.describe)("restored approval freshness", () => {
39
- (0, _vitest.it)("carries the target digest to disk and back, never the target", () => {
40
- const payload = (0, _transcriptPersistence.buildPayload)({
41
- messages: [{
42
- id: "m1",
43
- role: "user",
44
- text: "set it",
45
- toolCalls: [],
46
- blocks: []
47
- }],
48
- history: [],
49
- answers: {},
50
- usage: {
51
- input: 0,
52
- output: 0,
53
- requests: 0
54
- },
55
- pending: {
56
- id: "c1",
57
- toolId: "zustand",
58
- action: "setState",
59
- label: "Update the bag store",
60
- reason: "Replaces part of the store",
61
- params: {
62
- storeName: "bag",
63
- state: {
64
- qty: 14
65
- }
66
- },
67
- targetDigest: "1a2b3c:512",
68
- resolve: () => {}
69
- }
70
- });
71
- const json = JSON.stringify(payload);
72
- (0, _vitest.expect)(json).toContain("1a2b3c:512");
73
- const back = (0, _transcriptPersistence.parsePayload)(json);
74
- (0, _vitest.expect)(back?.pending?.targetDigest).toBe("1a2b3c:512");
75
- });
76
- });
77
- //# sourceMappingURL=systemLine.test.js.map
1
+ "use strict";var _vitest=require("vitest"),_askBuoyStore=require("./askBuoyStore"),_transcriptPersistence=require("./transcriptPersistence");(0,_vitest.beforeEach)(()=>_askBuoyStore.askBuoyStore.reset()),(0,_vitest.describe)("history-trimmed",()=>{(0,_vitest.it)("inserts a system line before the answer it affects",()=>{_askBuoyStore.askBuoyStore.addUser("turn off that override");const t=_askBuoyStore.askBuoyStore.startAssistant();_askBuoyStore.askBuoyStore.applyEvent(t,{type:"history-trimmed",droppedRounds:3}),_askBuoyStore.askBuoyStore.applyEvent(t,{type:"text",delta:"Turning it off."});const e=_askBuoyStore.askBuoyStore.getState().messages.map(t=>t.system?"system":t.role);(0,_vitest.expect)(e).toEqual(["user","system","assistant"]);const s=_askBuoyStore.askBuoyStore.getState().messages[1];(0,_vitest.expect)(s.text).toMatch(/3 exchanges/),(0,_vitest.expect)(s.text).toMatch(/changes bar still lists/)}),(0,_vitest.it)("singular for one round",()=>{const t=_askBuoyStore.askBuoyStore.startAssistant();_askBuoyStore.askBuoyStore.applyEvent(t,{type:"history-trimmed",droppedRounds:1}),(0,_vitest.expect)(_askBuoyStore.askBuoyStore.getState().messages[0].text).toMatch(/1 exchange\)/)})}),(0,_vitest.describe)("restored approval freshness",()=>{(0,_vitest.it)("carries the target digest to disk and back, never the target",()=>{const t=(0,_transcriptPersistence.buildPayload)({messages:[{id:"m1",role:"user",text:"set it",toolCalls:[],blocks:[]}],history:[],answers:{},usage:{input:0,output:0,requests:0},pending:{id:"c1",toolId:"zustand",action:"setState",label:"Update the bag store",reason:"Replaces part of the store",params:{storeName:"bag",state:{qty:14}},targetDigest:"1a2b3c:512",resolve:()=>{}}}),e=JSON.stringify(t);(0,_vitest.expect)(e).toContain("1a2b3c:512");const s=(0,_transcriptPersistence.parsePayload)(e);(0,_vitest.expect)(s?.pending?.targetDigest).toBe("1a2b3c:512")})});
@@ -1,17 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TICKET_PROMPT = void 0;
7
- /**
8
- * The "Summarize for a ticket" request, sent as an ordinary user message.
9
- *
10
- * One button, one canned sentence, because the machinery already exists: the
11
- * prompt teaches the `finding` block and the renderer draws it. What was
12
- * missing was a way to ASK for one without knowing the word, and a Copy that
13
- * includes it (see blockText.ts). Facts and inference are separated in the
14
- * ask, nothing is re-run to produce it, and nothing is submitted anywhere.
15
- */
16
- const TICKET_PROMPT = exports.TICKET_PROMPT = "Summarize this conversation as a bug ticket, using one buoy_ui finding block and nothing else. " + "Title it with the problem in one line. Evidence rows, in this order: Steps (what we did), Expected, Observed, " + "Build (dev or release, platform), Evidence (the exact requests, statuses, logs or values you actually saw this conversation), " + "Still applied (overrides or changes from your changes list that are still live, or 'none'). " + "Only facts you observed in this conversation; write 'unknown' where you don't know rather than guessing, and put anything " + "you inferred rather than saw in a final row labelled Inference. Do not run any tool or change anything to produce this.";
17
- //# sourceMappingURL=ticketPrompt.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.TICKET_PROMPT=void 0;const TICKET_PROMPT=exports.TICKET_PROMPT="Summarize this conversation as a bug ticket, using one buoy_ui finding block and nothing else. Title it with the problem in one line. Evidence rows, in this order: Steps (what we did), Expected, Observed, Build (dev or release, platform), Evidence (the exact requests, statuses, logs or values you actually saw this conversation), Still applied (overrides or changes from your changes list that are still live, or 'none'). Only facts you observed in this conversation; write 'unknown' where you don't know rather than guessing, and put anything you inferred rather than saw in a final row labelled Inference. Do not run any tool or change anything to produce this.";
@@ -1,81 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.hasTrace = hasTrace;
7
- exports.traceEntries = traceEntries;
8
- exports.traceToText = traceToText;
9
- /**
10
- * The agent's work for one answer, laid out in the order it happened.
11
- *
12
- * `traceEntries` is the ordering, shared by the collapsible strip in the chat
13
- * and by the JSON export — the two must agree, because the point of the export
14
- * is reading elsewhere the run you were just looking at. `traceToText` is the
15
- * plain-text rendering, kept for a quick paste into Slack; the debugging
16
- * artefact is `sessionExport.ts`.
17
- *
18
- * Reasoning and steps INTERLEAVE. One assistant bubble spans every turn of a
19
- * multi-step run, so the real shape is "think, act, think, act"; lumping the
20
- * thoughts at the top would misreport when the model knew what.
21
- */
22
-
23
- function traceEntries(message) {
24
- const thoughts = [...(message.reasoning ?? [])].sort((a, b) => a.afterCalls - b.afterCalls);
25
- const out = [];
26
- let t = 0;
27
- const drainTo = calls => {
28
- while (t < thoughts.length && thoughts[t].afterCalls <= calls) {
29
- out.push({
30
- kind: "thought",
31
- text: thoughts[t].text
32
- });
33
- t += 1;
34
- }
35
- };
36
- message.toolCalls.forEach((call, i) => {
37
- drainTo(i);
38
- out.push({
39
- kind: "step",
40
- n: i + 1,
41
- call
42
- });
43
- });
44
- // Anything the model thought after its last tool call — usually the reasoning
45
- // behind the answer itself, which is the most useful line in the trace.
46
- drainTo(message.toolCalls.length);
47
- return out;
48
- }
49
-
50
- /** Has this message anything to show? Drives whether the strip renders at all. */
51
- function hasTrace(message) {
52
- return (message.reasoning?.length ?? 0) > 0 || message.toolCalls.length > 0;
53
- }
54
- const statusWord = call => call.status === "ok" ? call.summary || "done" : call.status === "running" ? "running" : `${call.status}${call.summary ? ` — ${call.summary}` : ""}`;
55
-
56
- /**
57
- * The trace as plain text, for the clipboard.
58
- *
59
- * Indented under the answer it belongs to so a pasted session still reads as a
60
- * conversation rather than a log dump.
61
- */
62
- function traceToText(message, indent = " ") {
63
- const lines = [];
64
- for (const entry of traceEntries(message)) {
65
- if (entry.kind === "thought") {
66
- lines.push(`${indent}[thinking]`);
67
- for (const line of entry.text.trim().split("\n")) {
68
- lines.push(`${indent} ${line}`);
69
- }
70
- } else {
71
- const {
72
- n,
73
- call
74
- } = entry;
75
- lines.push(`${indent}[${n}] ${call.toolId}.${call.action} — ${statusWord(call)}`);
76
- if (call.params) lines.push(`${indent} ${call.params}`);
77
- }
78
- }
79
- return lines;
80
- }
81
- //# sourceMappingURL=traceText.js.map
1
+ "use strict";function traceEntries(t){const s=[...t.reasoning??[]].sort((t,s)=>t.afterCalls-s.afterCalls),e=[];let r=0;const n=t=>{for(;r<s.length&&s[r].afterCalls<=t;)e.push({kind:"thought",text:s[r].text}),r+=1};return t.toolCalls.forEach((t,s)=>{n(s),e.push({kind:"step",n:s+1,call:t})}),n(t.toolCalls.length),e}function hasTrace(t){return(t.reasoning?.length??0)>0||t.toolCalls.length>0}Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasTrace=hasTrace,exports.traceEntries=traceEntries,exports.traceToText=traceToText;const statusWord=t=>"ok"===t.status?t.summary||"done":"running"===t.status?"running":`${t.status}${t.summary?` — ${t.summary}`:""}`;function traceToText(t,s=" "){const e=[];for(const r of traceEntries(t))if("thought"===r.kind){e.push(`${s}[thinking]`);for(const t of r.text.trim().split("\n"))e.push(`${s} ${t}`)}else{const{n:t,call:n}=r;e.push(`${s}[${t}] ${n.toolId}.${n.action} — ${statusWord(n)}`),n.params&&e.push(`${s} ${n.params}`)}return e}
@@ -1,112 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _traceText = require("./traceText");
5
- /**
6
- * The agent's working, as text.
7
- *
8
- * This exists so a tester can paste a run somewhere and find the step that
9
- * broke, which puts two properties on it: reasoning and steps come out in the
10
- * order they HAPPENED (a multi-step turn is think, act, think, act — not all
11
- * the thoughts and then all the steps), and a failed step says so with its
12
- * parameters attached, since "storage.set failed" without the value it wrote
13
- * is not a bug report.
14
- */
15
-
16
- const call = (over = {}) => ({
17
- id: "c1",
18
- toolId: "zustand",
19
- action: "getStoreState",
20
- label: "Read the bag",
21
- status: "ok",
22
- summary: "Done",
23
- ...over
24
- });
25
- const msg = (over = {}) => ({
26
- id: "m1",
27
- role: "assistant",
28
- text: "Five items.",
29
- toolCalls: [],
30
- blocks: [],
31
- ...over
32
- });
33
- (0, _vitest.describe)("the order of a trace", () => {
34
- (0, _vitest.it)("interleaves thinking with the steps it led to", () => {
35
- const m = msg({
36
- toolCalls: [call({
37
- id: "c1"
38
- }), call({
39
- id: "c2",
40
- action: "setState"
41
- })],
42
- reasoning: [{
43
- text: "I should read the bag first.",
44
- afterCalls: 0
45
- }, {
46
- text: "Now I can write the new quantity.",
47
- afterCalls: 1
48
- }]
49
- });
50
- (0, _vitest.expect)((0, _traceText.traceEntries)(m).map(e => e.kind === "thought" ? "T" : `S${e.n}`)).toEqual(["T", "S1", "T", "S2"]);
51
- });
52
- (0, _vitest.it)("keeps a closing thought after the last step", () => {
53
- // Usually the reasoning behind the ANSWER, which is the most useful line
54
- // in the whole trace.
55
- const m = msg({
56
- toolCalls: [call()],
57
- reasoning: [{
58
- text: "That is everything the user asked for.",
59
- afterCalls: 1
60
- }]
61
- });
62
- const entries = (0, _traceText.traceEntries)(m);
63
- (0, _vitest.expect)(entries[entries.length - 1]).toEqual({
64
- kind: "thought",
65
- text: "That is everything the user asked for."
66
- });
67
- });
68
- (0, _vitest.it)("handles a turn with steps and no reasoning at all", () => {
69
- // The common case: gpt-4.1 and friends report none.
70
- const m = msg({
71
- toolCalls: [call()]
72
- });
73
- (0, _vitest.expect)((0, _traceText.traceEntries)(m)).toHaveLength(1);
74
- (0, _vitest.expect)((0, _traceText.hasTrace)(m)).toBe(true);
75
- });
76
- (0, _vitest.it)("has nothing to show for a plain answer", () => {
77
- (0, _vitest.expect)((0, _traceText.hasTrace)(msg())).toBe(false);
78
- });
79
- });
80
- (0, _vitest.describe)("the text it produces", () => {
81
- (0, _vitest.it)("names the tool, the action, the outcome and the parameters", () => {
82
- const m = msg({
83
- toolCalls: [call({
84
- params: '{"storeName":"Poké Mart bag"}'
85
- })]
86
- });
87
- (0, _vitest.expect)((0, _traceText.traceToText)(m)).toEqual([" [1] zustand.getStoreState — Done", ' {"storeName":"Poké Mart bag"}']);
88
- });
89
- (0, _vitest.it)("makes a failure and its parameters findable", () => {
90
- const m = msg({
91
- toolCalls: [call({
92
- toolId: "storage",
93
- action: "async.setItem",
94
- status: "failed",
95
- summary: "key not found",
96
- params: '{"key":"@pokemart/bag"}'
97
- })]
98
- });
99
- (0, _vitest.expect)((0, _traceText.traceToText)(m).join("\n")).toContain("failed — key not found");
100
- (0, _vitest.expect)((0, _traceText.traceToText)(m).join("\n")).toContain("@pokemart/bag");
101
- });
102
- (0, _vitest.it)("indents a multi-line thought so a pasted session still reads as one", () => {
103
- const m = msg({
104
- reasoning: [{
105
- text: "First line.\nSecond line.",
106
- afterCalls: 0
107
- }]
108
- });
109
- (0, _vitest.expect)((0, _traceText.traceToText)(m)).toEqual([" [thinking]", " First line.", " Second line."]);
110
- });
111
- });
112
- //# sourceMappingURL=traceText.test.js.map
1
+ "use strict";var _vitest=require("vitest"),_traceText=require("./traceText");const call=(t={})=>({id:"c1",toolId:"zustand",action:"getStoreState",label:"Read the bag",status:"ok",summary:"Done",...t}),msg=(t={})=>({id:"m1",role:"assistant",text:"Five items.",toolCalls:[],blocks:[],...t});(0,_vitest.describe)("the order of a trace",()=>{(0,_vitest.it)("interleaves thinking with the steps it led to",()=>{const t=msg({toolCalls:[call({id:"c1"}),call({id:"c2",action:"setState"})],reasoning:[{text:"I should read the bag first.",afterCalls:0},{text:"Now I can write the new quantity.",afterCalls:1}]});(0,_vitest.expect)((0,_traceText.traceEntries)(t).map(t=>"thought"===t.kind?"T":`S${t.n}`)).toEqual(["T","S1","T","S2"])}),(0,_vitest.it)("keeps a closing thought after the last step",()=>{const t=msg({toolCalls:[call()],reasoning:[{text:"That is everything the user asked for.",afterCalls:1}]}),e=(0,_traceText.traceEntries)(t);(0,_vitest.expect)(e[e.length-1]).toEqual({kind:"thought",text:"That is everything the user asked for."})}),(0,_vitest.it)("handles a turn with steps and no reasoning at all",()=>{const t=msg({toolCalls:[call()]});(0,_vitest.expect)((0,_traceText.traceEntries)(t)).toHaveLength(1),(0,_vitest.expect)((0,_traceText.hasTrace)(t)).toBe(!0)}),(0,_vitest.it)("has nothing to show for a plain answer",()=>{(0,_vitest.expect)((0,_traceText.hasTrace)(msg())).toBe(!1)})}),(0,_vitest.describe)("the text it produces",()=>{(0,_vitest.it)("names the tool, the action, the outcome and the parameters",()=>{const t=msg({toolCalls:[call({params:'{"storeName":"Poké Mart bag"}'})]});(0,_vitest.expect)((0,_traceText.traceToText)(t)).toEqual([" [1] zustand.getStoreState — Done",' {"storeName":"Poké Mart bag"}'])}),(0,_vitest.it)("makes a failure and its parameters findable",()=>{const t=msg({toolCalls:[call({toolId:"storage",action:"async.setItem",status:"failed",summary:"key not found",params:'{"key":"@pokemart/bag"}'})]});(0,_vitest.expect)((0,_traceText.traceToText)(t).join("\n")).toContain("failed — key not found"),(0,_vitest.expect)((0,_traceText.traceToText)(t).join("\n")).toContain("@pokemart/bag")}),(0,_vitest.it)("indents a multi-line thought so a pasted session still reads as one",()=>{const t=msg({reasoning:[{text:"First line.\nSecond line.",afterCalls:0}]});(0,_vitest.expect)((0,_traceText.traceToText)(t)).toEqual([" [thinking]"," First line."," Second line."])})});
@@ -1,297 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TRANSCRIPT_KEY = void 0;
7
- exports.buildPayload = buildPayload;
8
- exports.clearTranscript = clearTranscript;
9
- exports.fitToCaps = fitToCaps;
10
- exports.parsePayload = parsePayload;
11
- exports.readTranscript = readTranscript;
12
- exports.writeTranscript = writeTranscript;
13
- var _sharedUi = require("@buoy-gg/shared-ui");
14
- var _wire = require("../sync/wire");
15
- /**
16
- * The conversation, across a reload or a crash.
17
- *
18
- * This reverses a deliberate earlier decision, so the reasoning is worth
19
- * stating. The transcript used to live only in memory because it can quote
20
- * anything the agent read — a storage value, a response body, a customer
21
- * record — and a Buoy key on disk is readable by the Storage tool, which the
22
- * unauthenticated broker mirrors to every connected dashboard. That risk did
23
- * not go away; it is now a trade the host app makes knowingly, and can decline
24
- * with `askBuoy={{ persistTranscript: false }}`.
25
- *
26
- * What lowers it:
27
- * - Tool RESULTS are never written. The model's saved history keeps the shape
28
- * of each round (which tool ran, what it was asked) and replaces every result
29
- * payload with a placeholder — so the agent resumes knowing what it did, not
30
- * what it saw. Raw payloads are the sensitive part and they stay in memory.
31
- * - Everything written passes `redactForWire`, the same credential scrubber the
32
- * broker wire uses.
33
- * - It is capped, oldest-first, so a long QA session cannot grow a file without
34
- * bound.
35
- * - "New conversation" deletes it, rather than leaving the last chat on disk.
36
- */
37
-
38
- /** `@react_buoy` prefix, so the Storage tool treats it as one of its own. */
39
- const TRANSCRIPT_KEY = exports.TRANSCRIPT_KEY = `${_sharedUi.devToolsStorageKeys.base}_ask_buoy_transcript`;
40
-
41
- /**
42
- * Bumped when the saved shape changes; an older payload is dropped, not parsed.
43
- *
44
- * Purely ADDITIVE optional fields do not bump it — `pending` reads back as
45
- * absent from a v1 file written before it existed, and throwing away someone's
46
- * conversation to add a field they did not have is a worse trade than the one
47
- * this version number exists to make.
48
- */
49
- const VERSION = 1;
50
-
51
- /** Newest N bubbles. Beyond this a reader is scrolling history, not testing. */
52
- const MAX_MESSAGES = 60;
53
-
54
- /**
55
- * Hard ceiling on the file. Blocks carry image URLs and table rows, so a
56
- * message is not a small object; this is checked AFTER the message cap and
57
- * drops from the oldest end until it fits.
58
- */
59
- const MAX_BYTES = 256_000;
60
-
61
- /** What replaces a tool result. Addressed to the model, which will read it. */
62
- const DROPPED_RESULT = "[not kept across a restart — read it again if you need it]";
63
-
64
- /**
65
- * An approval the user never answered.
66
- *
67
- * Saved with the conversation because an unanswered question is exactly the
68
- * state a reload must not quietly resolve for them: nothing was tapped, so the
69
- * change is still pending as far as they know. `params` is the real call —
70
- * after a restart there is no turn left to resume, so Allow re-dispatches it.
71
- */
72
-
73
- function scrub(text) {
74
- return text ? (0, _wire.redactForWire)(text) : text;
75
- }
76
-
77
- /**
78
- * A bubble as it should look after a restart.
79
- *
80
- * `streaming` is cleared because nothing is streaming into a bubble the app
81
- * has just rebuilt, and a message caught mid-turn is marked as interrupted
82
- * rather than left looking like a silent, empty answer — which is exactly the
83
- * crash case this feature exists for. `actionState` is not saved at all: a
84
- * button stuck on "running" would be a lie about work that died with the
85
- * process.
86
- */
87
- function settle(m) {
88
- const cutOff = m.streaming === true;
89
- return {
90
- ...m,
91
- text: scrub(m.text),
92
- streaming: false,
93
- // The thinking view's payloads go through the same scrubber as the answer:
94
- // step parameters carry whatever the model passed a tool, which is exactly
95
- // where a token ends up when the agent has been asked to set one.
96
- reasoning: m.reasoning?.map(r => ({
97
- ...r,
98
- text: scrub(r.text)
99
- })),
100
- toolCalls: m.toolCalls.map(c => {
101
- const params = c.params ? scrub(c.params) : undefined;
102
- // `result` is dropped, never scrubbed. It is the tool payload itself —
103
- // a store's whole state, a response body — and "tool results are never
104
- // written to disk" is the promise this file is built on. It stays in
105
- // memory for the thinking view and the JSON export.
106
- const {
107
- result: _dropped,
108
- ...rest
109
- } = c;
110
- return c.status === "running" ? {
111
- ...rest,
112
- params,
113
- status: "failed",
114
- summary: "Interrupted"
115
- } : {
116
- ...rest,
117
- params
118
- };
119
- }),
120
- error: m.error ?? (cutOff && !m.text ? "This answer was interrupted — the app restarted mid-turn." : undefined)
121
- };
122
- }
123
-
124
- /** Model history with every tool result replaced by a placeholder. */
125
- function withoutResults(history) {
126
- return history.map(m => {
127
- if (m.role === "tool-results") {
128
- return {
129
- ...m,
130
- results: m.results.map(r => ({
131
- ...r,
132
- content: DROPPED_RESULT
133
- }))
134
- };
135
- }
136
- if (m.role === "assistant") return {
137
- ...m,
138
- text: scrub(m.text)
139
- };
140
- return {
141
- ...m,
142
- text: scrub(m.text)
143
- };
144
- });
145
- }
146
-
147
- /**
148
- * Trim to the caps. Messages and history are trimmed together and from the
149
- * same end, so what the user sees and what the model remembers stay the same
150
- * conversation rather than drifting apart across restarts.
151
- */
152
- function fitToCaps(payload) {
153
- let out = {
154
- ...payload,
155
- messages: payload.messages.slice(-MAX_MESSAGES),
156
- history: payload.history.slice(-MAX_MESSAGES * 2)
157
- };
158
- let json = JSON.stringify(out);
159
- while (json.length > MAX_BYTES && out.messages.length > 1) {
160
- out = {
161
- ...out,
162
- messages: out.messages.slice(1),
163
- history: out.history.slice(Math.min(2, out.history.length))
164
- };
165
- json = JSON.stringify(out);
166
- }
167
- return out;
168
- }
169
-
170
- /**
171
- * The pending approval, if it is safe to bring back.
172
- *
173
- * Params are NOT scrubbed on the way out, and that is the point of the check:
174
- * a redacted token written back into the call is no longer the change the user
175
- * was asked about, so re-running it would apply something they never saw. A
176
- * call the wire scrubber touches at all is therefore not persisted — an action
177
- * carrying a credential is precisely the one that should not come back after a
178
- * restart and run itself. The card is lost in that case, which is the same
179
- * behaviour as before this existed.
180
- */
181
- function storableApproval(pending) {
182
- // A RESTORED card is saved again too: reloading twice without answering must
183
- // not be the thing that finally loses the question.
184
- if (!pending) return null;
185
- const params = pending.params;
186
- if (!params) return null;
187
- let json;
188
- try {
189
- json = JSON.stringify(params);
190
- } catch {
191
- return null;
192
- }
193
- if ((0, _wire.redactForWire)(json) !== json) return null;
194
- return {
195
- id: pending.id,
196
- toolId: pending.toolId,
197
- action: pending.action,
198
- label: scrub(pending.label),
199
- description: pending.description ? scrub(pending.description) : undefined,
200
- reason: scrub(pending.reason),
201
- params,
202
- targetDigest: pending.targetDigest
203
- };
204
- }
205
- function isStoredApproval(value) {
206
- if (typeof value !== "object" || value === null) return false;
207
- const v = value;
208
- return typeof v.id === "string" && typeof v.toolId === "string" && typeof v.action === "string" && typeof v.label === "string" && typeof v.reason === "string" && typeof v.params === "object" && v.params !== null;
209
- }
210
-
211
- /**
212
- * Ledger entries safe to write.
213
- *
214
- * Same rule as `storableApproval`: an entry the wire scrubber would touch
215
- * carries a credential in the value it is holding for the undo, and scrubbing
216
- * it would make the undo restore a redacted string over the real one. Such an
217
- * entry is dropped rather than rewritten — losing an undo is recoverable,
218
- * writing "[redacted]" into the user's storage is not.
219
- */
220
- function storableLedger(entries) {
221
- if (!entries?.length) return undefined;
222
- const kept = entries.filter(e => {
223
- try {
224
- const json = JSON.stringify(e);
225
- return (0, _wire.redactForWire)(json) === json;
226
- } catch {
227
- return false;
228
- }
229
- });
230
- return kept.length ? kept : undefined;
231
- }
232
- function buildPayload(input) {
233
- return fitToCaps({
234
- v: VERSION,
235
- savedAt: Date.now(),
236
- messages: input.messages.map(settle),
237
- history: withoutResults(input.history),
238
- answers: input.answers,
239
- usage: input.usage,
240
- pending: storableApproval(input.pending),
241
- ledger: storableLedger(input.ledger),
242
- queued: input.queued?.length ? input.queued.map(q => ({
243
- id: q.id,
244
- text: scrub(q.text)
245
- })) : undefined
246
- });
247
- }
248
-
249
- /** Anything unparseable, or from an older shape, is treated as "no transcript". */
250
- function parsePayload(raw) {
251
- if (!raw) return null;
252
- try {
253
- const parsed = JSON.parse(raw);
254
- if (parsed?.v !== VERSION || !Array.isArray(parsed.messages)) return null;
255
- if (parsed.messages.length === 0) return null;
256
- return {
257
- v: VERSION,
258
- savedAt: typeof parsed.savedAt === "number" ? parsed.savedAt : 0,
259
- messages: parsed.messages,
260
- history: Array.isArray(parsed.history) ? parsed.history : [],
261
- answers: parsed.answers ?? {},
262
- usage: parsed.usage ?? {
263
- input: 0,
264
- output: 0,
265
- requests: 0
266
- },
267
- pending: isStoredApproval(parsed.pending) ? parsed.pending : null,
268
- ledger: Array.isArray(parsed.ledger) ? parsed.ledger.filter(e => typeof e === "object" && e !== null && typeof e.id === "string") : undefined,
269
- queued: Array.isArray(parsed.queued) ? parsed.queued.filter(q => typeof q === "object" && q !== null && typeof q.id === "string" && typeof q.text === "string") : undefined
270
- };
271
- } catch {
272
- return null;
273
- }
274
- }
275
- async function readTranscript() {
276
- try {
277
- return parsePayload(await _sharedUi.persistentStorage.getItem(TRANSCRIPT_KEY));
278
- } catch {
279
- return null;
280
- }
281
- }
282
- async function writeTranscript(payload) {
283
- try {
284
- await _sharedUi.persistentStorage.setItem(TRANSCRIPT_KEY, JSON.stringify(payload));
285
- } catch {
286
- // A transcript that cannot be saved must never break the chat that
287
- // produced it.
288
- }
289
- }
290
- async function clearTranscript() {
291
- try {
292
- await _sharedUi.persistentStorage.removeItem(TRANSCRIPT_KEY);
293
- } catch {
294
- /* nothing to do — see writeTranscript */
295
- }
296
- }
297
- //# sourceMappingURL=transcriptPersistence.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.TRANSCRIPT_KEY=void 0,exports.buildPayload=buildPayload,exports.clearTranscript=clearTranscript,exports.fitToCaps=fitToCaps,exports.parsePayload=parsePayload,exports.readTranscript=readTranscript,exports.writeTranscript=writeTranscript;var _sharedUi=require("@buoy-gg/shared-ui"),_wire=require("../sync/wire");const TRANSCRIPT_KEY=exports.TRANSCRIPT_KEY=`${_sharedUi.devToolsStorageKeys.base}_ask_buoy_transcript`,VERSION=1,MAX_MESSAGES=60,MAX_BYTES=256e3,DROPPED_RESULT="[not kept across a restart — read it again if you need it]";function scrub(e){return e?(0,_wire.redactForWire)(e):e}function settle(e){const r=!0===e.streaming;return{...e,text:scrub(e.text),streaming:!1,reasoning:e.reasoning?.map(e=>({...e,text:scrub(e.text)})),toolCalls:e.toolCalls.map(e=>{const r=e.params?scrub(e.params):void 0,{result:t,...s}=e;return"running"===e.status?{...s,params:r,status:"failed",summary:"Interrupted"}:{...s,params:r}}),error:e.error??(r&&!e.text?"This answer was interrupted — the app restarted mid-turn.":void 0)}}function withoutResults(e){return e.map(e=>"tool-results"===e.role?{...e,results:e.results.map(e=>({...e,content:DROPPED_RESULT}))}:(e.role,{...e,text:scrub(e.text)}))}function fitToCaps(e){let r={...e,messages:e.messages.slice(-MAX_MESSAGES),history:e.history.slice(2*-MAX_MESSAGES)},t=JSON.stringify(r);for(;t.length>MAX_BYTES&&r.messages.length>1;)r={...r,messages:r.messages.slice(1),history:r.history.slice(Math.min(2,r.history.length))},t=JSON.stringify(r);return r}function storableApproval(e){if(!e)return null;const r=e.params;if(!r)return null;let t;try{t=JSON.stringify(r)}catch{return null}return(0,_wire.redactForWire)(t)!==t?null:{id:e.id,toolId:e.toolId,action:e.action,label:scrub(e.label),description:e.description?scrub(e.description):void 0,reason:scrub(e.reason),params:r,targetDigest:e.targetDigest}}function isStoredApproval(e){if("object"!=typeof e||null===e)return!1;const r=e;return"string"==typeof r.id&&"string"==typeof r.toolId&&"string"==typeof r.action&&"string"==typeof r.label&&"string"==typeof r.reason&&"object"==typeof r.params&&null!==r.params}function storableLedger(e){if(!e?.length)return;const r=e.filter(e=>{try{const r=JSON.stringify(e);return(0,_wire.redactForWire)(r)===r}catch{return!1}});return r.length?r:void 0}function buildPayload(e){return fitToCaps({v:VERSION,savedAt:Date.now(),messages:e.messages.map(settle),history:withoutResults(e.history),answers:e.answers,usage:e.usage,pending:storableApproval(e.pending),ledger:storableLedger(e.ledger),queued:e.queued?.length?e.queued.map(e=>({id:e.id,text:scrub(e.text)})):void 0})}function parsePayload(e){if(!e)return null;try{const r=JSON.parse(e);return r?.v===VERSION&&Array.isArray(r.messages)?0===r.messages.length?null:{v:VERSION,savedAt:"number"==typeof r.savedAt?r.savedAt:0,messages:r.messages,history:Array.isArray(r.history)?r.history:[],answers:r.answers??{},usage:r.usage??{input:0,output:0,requests:0},pending:isStoredApproval(r.pending)?r.pending:null,ledger:Array.isArray(r.ledger)?r.ledger.filter(e=>"object"==typeof e&&null!==e&&"string"==typeof e.id):void 0,queued:Array.isArray(r.queued)?r.queued.filter(e=>"object"==typeof e&&null!==e&&"string"==typeof e.id&&"string"==typeof e.text):void 0}:null}catch{return null}}async function readTranscript(){try{return parsePayload(await _sharedUi.persistentStorage.getItem(TRANSCRIPT_KEY))}catch{return null}}async function writeTranscript(e){try{await _sharedUi.persistentStorage.setItem(TRANSCRIPT_KEY,JSON.stringify(e))}catch{}}async function clearTranscript(){try{await _sharedUi.persistentStorage.removeItem(TRANSCRIPT_KEY)}catch{}}