@buoy-gg/ask-buoy 7.0.41 → 7.0.43

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 (313) hide show
  1. package/README.md +13 -98
  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 -783
  6. package/lib/commonjs/blocks/ExtraBlocks.js +1 -1862
  7. package/lib/commonjs/blocks/MediaBlocks.js +1 -158
  8. package/lib/commonjs/blocks/ReceiptBlocks.js +2 -592
  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/blocks/ruleStates.js +1 -39
  20. package/lib/commonjs/components/ApprovalCard.js +1 -297
  21. package/lib/commonjs/components/AskBuoyHeader.js +1 -196
  22. package/lib/commonjs/components/AskBuoyIcon.js +1 -19
  23. package/lib/commonjs/components/AskBuoyModal.js +2 -482
  24. package/lib/commonjs/components/AskBuoySettings.js +1 -181
  25. package/lib/commonjs/components/ChangesBar.js +1 -212
  26. package/lib/commonjs/components/Composer.js +1 -255
  27. package/lib/commonjs/components/EmptyState.js +1 -161
  28. package/lib/commonjs/components/KeyboardPad.js +1 -80
  29. package/lib/commonjs/components/Markdown.js +1 -310
  30. package/lib/commonjs/components/MessageList.js +1 -970
  31. package/lib/commonjs/components/QueuedMessages.js +1 -145
  32. package/lib/commonjs/components/ThinkingStrip.js +1 -223
  33. package/lib/commonjs/components/TypingDots.js +1 -63
  34. package/lib/commonjs/components/markdownParse.js +1 -131
  35. package/lib/commonjs/components/markdownParse.test.js +1 -99
  36. package/lib/commonjs/components/useCopyAction.js +1 -50
  37. package/lib/commonjs/index.js +1 -252
  38. package/lib/commonjs/preset.js +1 -91
  39. package/lib/commonjs/store/activityGroups.js +1 -110
  40. package/lib/commonjs/store/activityGroups.test.js +1 -78
  41. package/lib/commonjs/store/askBuoySettings.js +1 -72
  42. package/lib/commonjs/store/askBuoyStore.js +2 -588
  43. package/lib/commonjs/store/blockPlacement.js +1 -64
  44. package/lib/commonjs/store/blockPlacement.test.js +1 -123
  45. package/lib/commonjs/store/queue.test.js +1 -150
  46. package/lib/commonjs/store/resetConversation.js +1 -77
  47. package/lib/commonjs/store/restorePending.test.js +1 -63
  48. package/lib/commonjs/store/restoredIds.test.js +1 -47
  49. package/lib/commonjs/store/suggestions.js +1 -54
  50. package/lib/commonjs/store/suggestions.test.js +1 -58
  51. package/lib/commonjs/store/systemLine.test.js +1 -77
  52. package/lib/commonjs/store/ticketPrompt.js +1 -17
  53. package/lib/commonjs/store/traceText.js +1 -81
  54. package/lib/commonjs/store/traceText.test.js +1 -112
  55. package/lib/commonjs/store/transcriptPersistence.js +1 -297
  56. package/lib/commonjs/store/transcriptPersistence.test.js +1 -333
  57. package/lib/commonjs/store/turnRendering.test.js +1 -151
  58. package/lib/commonjs/store/useAskBuoy.js +1 -651
  59. package/lib/commonjs/store/useAskBuoySettings.js +1 -14
  60. package/lib/commonjs/sync/askBuoySyncAdapter.js +1 -153
  61. package/lib/commonjs/sync/askBuoySyncAdapter.test.js +1 -141
  62. package/lib/commonjs/sync/wire.js +1 -58
  63. package/lib/commonjs/types.js +1 -6
  64. package/lib/module/blocks/AskBlocks.js +1 -331
  65. package/lib/module/blocks/BlockRenderer.js +1 -257
  66. package/lib/module/blocks/ChromePrototypes.js +1 -503
  67. package/lib/module/blocks/DataBlocks.js +1 -769
  68. package/lib/module/blocks/ExtraBlocks.js +1 -1835
  69. package/lib/module/blocks/MediaBlocks.js +1 -153
  70. package/lib/module/blocks/ReceiptBlocks.js +2 -580
  71. package/lib/module/blocks/blockText.js +1 -55
  72. package/lib/module/blocks/blockText.test.js +1 -53
  73. package/lib/module/blocks/context.js +1 -35
  74. package/lib/module/blocks/icons.js +1 -91
  75. package/lib/module/blocks/index.js +1 -8
  76. package/lib/module/blocks/listRow.test.js +1 -56
  77. package/lib/module/blocks/pageState.js +1 -30
  78. package/lib/module/blocks/pageState.test.js +1 -56
  79. package/lib/module/blocks/primitives.js +1 -445
  80. package/lib/module/blocks/primitivesIndex.js +1 -5
  81. package/lib/module/blocks/ruleStates.js +1 -35
  82. package/lib/module/components/ApprovalCard.js +1 -292
  83. package/lib/module/components/AskBuoyHeader.js +1 -193
  84. package/lib/module/components/AskBuoyIcon.js +1 -8
  85. package/lib/module/components/AskBuoyModal.js +2 -477
  86. package/lib/module/components/AskBuoySettings.js +1 -176
  87. package/lib/module/components/ChangesBar.js +1 -206
  88. package/lib/module/components/Composer.js +1 -250
  89. package/lib/module/components/EmptyState.js +1 -156
  90. package/lib/module/components/KeyboardPad.js +1 -75
  91. package/lib/module/components/Markdown.js +1 -305
  92. package/lib/module/components/MessageList.js +1 -964
  93. package/lib/module/components/QueuedMessages.js +1 -140
  94. package/lib/module/components/ThinkingStrip.js +1 -218
  95. package/lib/module/components/TypingDots.js +1 -58
  96. package/lib/module/components/markdownParse.js +1 -125
  97. package/lib/module/components/markdownParse.test.js +1 -98
  98. package/lib/module/components/useCopyAction.js +1 -46
  99. package/lib/module/index.js +1 -34
  100. package/lib/module/preset.js +1 -74
  101. package/lib/module/store/activityGroups.js +1 -103
  102. package/lib/module/store/activityGroups.test.js +1 -77
  103. package/lib/module/store/askBuoySettings.js +1 -67
  104. package/lib/module/store/askBuoyStore.js +2 -582
  105. package/lib/module/store/blockPlacement.js +1 -59
  106. package/lib/module/store/blockPlacement.test.js +1 -122
  107. package/lib/module/store/queue.test.js +1 -149
  108. package/lib/module/store/resetConversation.js +1 -72
  109. package/lib/module/store/restorePending.test.js +1 -62
  110. package/lib/module/store/restoredIds.test.js +1 -46
  111. package/lib/module/store/suggestions.js +1 -49
  112. package/lib/module/store/suggestions.test.js +1 -57
  113. package/lib/module/store/systemLine.test.js +1 -76
  114. package/lib/module/store/ticketPrompt.js +1 -13
  115. package/lib/module/store/traceText.js +1 -75
  116. package/lib/module/store/traceText.test.js +1 -111
  117. package/lib/module/store/transcriptPersistence.js +1 -287
  118. package/lib/module/store/transcriptPersistence.test.js +1 -332
  119. package/lib/module/store/turnRendering.test.js +1 -150
  120. package/lib/module/store/useAskBuoy.js +1 -646
  121. package/lib/module/store/useAskBuoySettings.js +1 -9
  122. package/lib/module/sync/askBuoySyncAdapter.js +1 -148
  123. package/lib/module/sync/askBuoySyncAdapter.test.js +1 -140
  124. package/lib/module/sync/wire.js +1 -47
  125. package/lib/module/types.js +1 -4
  126. package/lib/web/index.mjs +11 -12
  127. package/package.json +8 -12
  128. package/lib/commonjs/blocks/AskBlocks.js.map +0 -1
  129. package/lib/commonjs/blocks/BlockRenderer.js.map +0 -1
  130. package/lib/commonjs/blocks/ChromePrototypes.js.map +0 -1
  131. package/lib/commonjs/blocks/DataBlocks.js.map +0 -1
  132. package/lib/commonjs/blocks/ExtraBlocks.js.map +0 -1
  133. package/lib/commonjs/blocks/MediaBlocks.js.map +0 -1
  134. package/lib/commonjs/blocks/ReceiptBlocks.js.map +0 -1
  135. package/lib/commonjs/blocks/blockText.js.map +0 -1
  136. package/lib/commonjs/blocks/blockText.test.js.map +0 -1
  137. package/lib/commonjs/blocks/context.js.map +0 -1
  138. package/lib/commonjs/blocks/icons.js.map +0 -1
  139. package/lib/commonjs/blocks/index.js.map +0 -1
  140. package/lib/commonjs/blocks/listRow.test.js.map +0 -1
  141. package/lib/commonjs/blocks/pageState.js.map +0 -1
  142. package/lib/commonjs/blocks/pageState.test.js.map +0 -1
  143. package/lib/commonjs/blocks/primitives.js.map +0 -1
  144. package/lib/commonjs/blocks/primitivesIndex.js.map +0 -1
  145. package/lib/commonjs/blocks/ruleStates.js.map +0 -1
  146. package/lib/commonjs/components/ApprovalCard.js.map +0 -1
  147. package/lib/commonjs/components/AskBuoyHeader.js.map +0 -1
  148. package/lib/commonjs/components/AskBuoyIcon.js.map +0 -1
  149. package/lib/commonjs/components/AskBuoyModal.js.map +0 -1
  150. package/lib/commonjs/components/AskBuoySettings.js.map +0 -1
  151. package/lib/commonjs/components/ChangesBar.js.map +0 -1
  152. package/lib/commonjs/components/Composer.js.map +0 -1
  153. package/lib/commonjs/components/EmptyState.js.map +0 -1
  154. package/lib/commonjs/components/KeyboardPad.js.map +0 -1
  155. package/lib/commonjs/components/Markdown.js.map +0 -1
  156. package/lib/commonjs/components/MessageList.js.map +0 -1
  157. package/lib/commonjs/components/QueuedMessages.js.map +0 -1
  158. package/lib/commonjs/components/ThinkingStrip.js.map +0 -1
  159. package/lib/commonjs/components/TypingDots.js.map +0 -1
  160. package/lib/commonjs/components/markdownParse.js.map +0 -1
  161. package/lib/commonjs/components/markdownParse.test.js.map +0 -1
  162. package/lib/commonjs/components/useCopyAction.js.map +0 -1
  163. package/lib/commonjs/index.js.map +0 -1
  164. package/lib/commonjs/preset.js.map +0 -1
  165. package/lib/commonjs/store/activityGroups.js.map +0 -1
  166. package/lib/commonjs/store/activityGroups.test.js.map +0 -1
  167. package/lib/commonjs/store/askBuoySettings.js.map +0 -1
  168. package/lib/commonjs/store/askBuoyStore.js.map +0 -1
  169. package/lib/commonjs/store/blockPlacement.js.map +0 -1
  170. package/lib/commonjs/store/blockPlacement.test.js.map +0 -1
  171. package/lib/commonjs/store/queue.test.js.map +0 -1
  172. package/lib/commonjs/store/resetConversation.js.map +0 -1
  173. package/lib/commonjs/store/restorePending.test.js.map +0 -1
  174. package/lib/commonjs/store/restoredIds.test.js.map +0 -1
  175. package/lib/commonjs/store/suggestions.js.map +0 -1
  176. package/lib/commonjs/store/suggestions.test.js.map +0 -1
  177. package/lib/commonjs/store/systemLine.test.js.map +0 -1
  178. package/lib/commonjs/store/ticketPrompt.js.map +0 -1
  179. package/lib/commonjs/store/traceText.js.map +0 -1
  180. package/lib/commonjs/store/traceText.test.js.map +0 -1
  181. package/lib/commonjs/store/transcriptPersistence.js.map +0 -1
  182. package/lib/commonjs/store/transcriptPersistence.test.js.map +0 -1
  183. package/lib/commonjs/store/turnRendering.test.js.map +0 -1
  184. package/lib/commonjs/store/useAskBuoy.js.map +0 -1
  185. package/lib/commonjs/store/useAskBuoySettings.js.map +0 -1
  186. package/lib/commonjs/sync/askBuoySyncAdapter.js.map +0 -1
  187. package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +0 -1
  188. package/lib/commonjs/sync/wire.js.map +0 -1
  189. package/lib/commonjs/types.js.map +0 -1
  190. package/lib/module/blocks/AskBlocks.js.map +0 -1
  191. package/lib/module/blocks/BlockRenderer.js.map +0 -1
  192. package/lib/module/blocks/ChromePrototypes.js.map +0 -1
  193. package/lib/module/blocks/DataBlocks.js.map +0 -1
  194. package/lib/module/blocks/ExtraBlocks.js.map +0 -1
  195. package/lib/module/blocks/MediaBlocks.js.map +0 -1
  196. package/lib/module/blocks/ReceiptBlocks.js.map +0 -1
  197. package/lib/module/blocks/blockText.js.map +0 -1
  198. package/lib/module/blocks/blockText.test.js.map +0 -1
  199. package/lib/module/blocks/context.js.map +0 -1
  200. package/lib/module/blocks/icons.js.map +0 -1
  201. package/lib/module/blocks/index.js.map +0 -1
  202. package/lib/module/blocks/listRow.test.js.map +0 -1
  203. package/lib/module/blocks/pageState.js.map +0 -1
  204. package/lib/module/blocks/pageState.test.js.map +0 -1
  205. package/lib/module/blocks/primitives.js.map +0 -1
  206. package/lib/module/blocks/primitivesIndex.js.map +0 -1
  207. package/lib/module/blocks/ruleStates.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/blocks/ruleStates.d.ts.map +0 -1
  270. package/lib/typescript/components/ApprovalCard.d.ts.map +0 -1
  271. package/lib/typescript/components/AskBuoyHeader.d.ts.map +0 -1
  272. package/lib/typescript/components/AskBuoyIcon.d.ts.map +0 -1
  273. package/lib/typescript/components/AskBuoyModal.d.ts.map +0 -1
  274. package/lib/typescript/components/AskBuoySettings.d.ts.map +0 -1
  275. package/lib/typescript/components/ChangesBar.d.ts.map +0 -1
  276. package/lib/typescript/components/Composer.d.ts.map +0 -1
  277. package/lib/typescript/components/EmptyState.d.ts.map +0 -1
  278. package/lib/typescript/components/KeyboardPad.d.ts.map +0 -1
  279. package/lib/typescript/components/Markdown.d.ts.map +0 -1
  280. package/lib/typescript/components/MessageList.d.ts.map +0 -1
  281. package/lib/typescript/components/QueuedMessages.d.ts.map +0 -1
  282. package/lib/typescript/components/ThinkingStrip.d.ts.map +0 -1
  283. package/lib/typescript/components/TypingDots.d.ts.map +0 -1
  284. package/lib/typescript/components/markdownParse.d.ts.map +0 -1
  285. package/lib/typescript/components/markdownParse.test.d.ts.map +0 -1
  286. package/lib/typescript/components/useCopyAction.d.ts.map +0 -1
  287. package/lib/typescript/index.d.ts.map +0 -1
  288. package/lib/typescript/preset.d.ts.map +0 -1
  289. package/lib/typescript/store/activityGroups.d.ts.map +0 -1
  290. package/lib/typescript/store/activityGroups.test.d.ts.map +0 -1
  291. package/lib/typescript/store/askBuoySettings.d.ts.map +0 -1
  292. package/lib/typescript/store/askBuoyStore.d.ts.map +0 -1
  293. package/lib/typescript/store/blockPlacement.d.ts.map +0 -1
  294. package/lib/typescript/store/blockPlacement.test.d.ts.map +0 -1
  295. package/lib/typescript/store/queue.test.d.ts.map +0 -1
  296. package/lib/typescript/store/resetConversation.d.ts.map +0 -1
  297. package/lib/typescript/store/restorePending.test.d.ts.map +0 -1
  298. package/lib/typescript/store/restoredIds.test.d.ts.map +0 -1
  299. package/lib/typescript/store/suggestions.d.ts.map +0 -1
  300. package/lib/typescript/store/suggestions.test.d.ts.map +0 -1
  301. package/lib/typescript/store/systemLine.test.d.ts.map +0 -1
  302. package/lib/typescript/store/ticketPrompt.d.ts.map +0 -1
  303. package/lib/typescript/store/traceText.d.ts.map +0 -1
  304. package/lib/typescript/store/traceText.test.d.ts.map +0 -1
  305. package/lib/typescript/store/transcriptPersistence.d.ts.map +0 -1
  306. package/lib/typescript/store/transcriptPersistence.test.d.ts.map +0 -1
  307. package/lib/typescript/store/turnRendering.test.d.ts.map +0 -1
  308. package/lib/typescript/store/useAskBuoy.d.ts.map +0 -1
  309. package/lib/typescript/store/useAskBuoySettings.d.ts.map +0 -1
  310. package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +0 -1
  311. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +0 -1
  312. package/lib/typescript/sync/wire.d.ts.map +0 -1
  313. package/lib/typescript/types.d.ts.map +0 -1
@@ -1,123 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _blockPlacement = require("./blockPlacement");
5
- /**
6
- * The bug this file exists for: a model-authored block carries the id of the
7
- * `buoy_ui` call that made it, `buoy_ui` never draws an activity row, and the
8
- * nesting rule ("anything from a call, unless it's a write receipt") swept it
9
- * into a bucket keyed by a row that does not exist. Two consecutive asks for
10
- * pictures of a shop came back as prose.
11
- */
12
-
13
- const placed = (b, forToolCallId) => ({
14
- block: b,
15
- forToolCallId
16
- });
17
- const grid = (id = "ui1") => placed({
18
- id,
19
- kind: "imageGrid",
20
- source: "model",
21
- images: [{
22
- url: "https://cdn.example.com/25.png",
23
- alt: "Pikachu"
24
- }]
25
- }, "call-ui");
26
- (0, _vitest.describe)("model-authored blocks", () => {
27
- (0, _vitest.it)("renders in the answer, never nested under a step that has no row", () => {
28
- const {
29
- afterText,
30
- nested
31
- } = (0, _blockPlacement.placeBlocks)([grid()], ["c1"]);
32
- (0, _vitest.expect)(afterText.map(p => p.block.id)).toEqual(["ui1"]);
33
- (0, _vitest.expect)(nested.size).toBe(0);
34
- });
35
- (0, _vitest.it)("still renders even when a step with that id somehow exists", () => {
36
- const {
37
- afterText
38
- } = (0, _blockPlacement.placeBlocks)([grid()], ["call-ui"]);
39
- (0, _vitest.expect)(afterText.map(p => p.block.id)).toEqual(["ui1"]);
40
- });
41
- });
42
- (0, _vitest.describe)("receipts", () => {
43
- (0, _vitest.it)("folds a read receipt into its own step row", () => {
44
- const read = placed({
45
- id: "r1",
46
- kind: "keyValue",
47
- source: "live",
48
- pairs: []
49
- }, "c1");
50
- const {
51
- nested,
52
- afterText
53
- } = (0, _blockPlacement.placeBlocks)([read], ["c1"]);
54
- (0, _vitest.expect)(afterText).toEqual([]);
55
- (0, _vitest.expect)(nested.get("c1")?.map(b => b.id)).toEqual(["r1"]);
56
- });
57
- (0, _vitest.it)("keeps a write receipt afterText — the user must see it without asking", () => {
58
- const write = placed({
59
- id: "w1",
60
- kind: "diff",
61
- source: "changed",
62
- changes: []
63
- }, "c1");
64
- const {
65
- nested,
66
- afterText
67
- } = (0, _blockPlacement.placeBlocks)([write], ["c1"]);
68
- (0, _vitest.expect)(nested.size).toBe(0);
69
- (0, _vitest.expect)(afterText.map(p => p.block.id)).toEqual(["w1"]);
70
- });
71
- (0, _vitest.it)("falls back to afterText when its step row was never drawn", () => {
72
- const orphan = placed({
73
- id: "r2",
74
- kind: "keyValue",
75
- source: "live",
76
- pairs: []
77
- }, "gone");
78
- const {
79
- afterText
80
- } = (0, _blockPlacement.placeBlocks)([orphan], []);
81
- (0, _vitest.expect)(afterText.map(p => p.block.id)).toEqual(["r2"]);
82
- });
83
- });
84
- (0, _vitest.describe)("ask blocks", () => {
85
- (0, _vitest.it)("come out in their own bucket, after the answer", () => {
86
- const confirm = placed({
87
- id: "a1",
88
- kind: "confirm",
89
- source: "model",
90
- change: "Wipe storage"
91
- }, "call-ui");
92
- const {
93
- ask,
94
- afterText,
95
- nested
96
- } = (0, _blockPlacement.placeBlocks)([confirm, grid("ui2")], ["c1"]);
97
- (0, _vitest.expect)(ask.map(p => p.block.id)).toEqual(["a1"]);
98
- (0, _vitest.expect)(afterText.map(p => p.block.id)).toEqual(["ui2"]);
99
- (0, _vitest.expect)(nested.size).toBe(0);
100
- });
101
- });
102
-
103
- /**
104
- * The order the transcript draws these in, asserted here rather than left to
105
- * MessageList's JSX.
106
- *
107
- * Off a real device: "show me all the pokemon from our poke mart shop". The
108
- * agent navigated to /shop, paged through 28 menu items and built the grid —
109
- * and the grid rendered at the TOP of the bubble with five paragraphs of
110
- * narration beneath it, so the finished answer arrived before the sentence
111
- * introducing it. The bucket is named for its position so a future edit has
112
- * to contradict the name to put it back.
113
- */
114
- (0, _vitest.describe)("the answer comes after the prose", () => {
115
- (0, _vitest.it)("puts a model-authored card in the after-text bucket, never before it", () => {
116
- const placed = (0, _blockPlacement.placeBlocks)([grid()], ["c1"]);
117
- (0, _vitest.expect)(placed.afterText.map(p => p.block.id)).toEqual(["ui1"]);
118
- // `nested` is the only bucket that draws ABOVE the text (inside the
119
- // activity card's step rows), and only read receipts belong there.
120
- (0, _vitest.expect)(placed.nested.size).toBe(0);
121
- });
122
- });
123
- //# sourceMappingURL=blockPlacement.test.js.map
1
+ "use strict";var _vitest=require("vitest");var _blockPlacement=require("./blockPlacement");const placed=(e,t)=>({block:e,forToolCallId:t});const grid=(e="ui1")=>placed({id:e,kind:"imageGrid",source:"model",images:[{url:"https://cdn.example.com/25.png",alt:"Pikachu"}]},"call-ui");(0,_vitest.describe)("model-authored blocks",()=>{(0,_vitest.it)("renders in the answer, never nested under a step that has no row",()=>{const{afterText:e,nested:t}=(0,_blockPlacement.placeBlocks)([grid()],["c1"]);(0,_vitest.expect)(e.map(c=>c.block.id)).toEqual(["ui1"]);(0,_vitest.expect)(t.size).toBe(0)});(0,_vitest.it)("still renders even when a step with that id somehow exists",()=>{const{afterText:e}=(0,_blockPlacement.placeBlocks)([grid()],["call-ui"]);(0,_vitest.expect)(e.map(t=>t.block.id)).toEqual(["ui1"])})});(0,_vitest.describe)("receipts",()=>{(0,_vitest.it)("folds a read receipt into its own step row",()=>{const e=placed({id:"r1",kind:"keyValue",source:"live",pairs:[]},"c1");const{nested:t,afterText:c}=(0,_blockPlacement.placeBlocks)([e],["c1"]);(0,_vitest.expect)(c).toEqual([]);(0,_vitest.expect)(t.get("c1")?.map(a=>a.id)).toEqual(["r1"])});(0,_vitest.it)("keeps a write receipt afterText \u2014 the user must see it without asking",()=>{const e=placed({id:"w1",kind:"diff",source:"changed",changes:[]},"c1");const{nested:t,afterText:c}=(0,_blockPlacement.placeBlocks)([e],["c1"]);(0,_vitest.expect)(t.size).toBe(0);(0,_vitest.expect)(c.map(a=>a.block.id)).toEqual(["w1"])});(0,_vitest.it)("falls back to afterText when its step row was never drawn",()=>{const e=placed({id:"r2",kind:"keyValue",source:"live",pairs:[]},"gone");const{afterText:t}=(0,_blockPlacement.placeBlocks)([e],[]);(0,_vitest.expect)(t.map(c=>c.block.id)).toEqual(["r2"])})});(0,_vitest.describe)("ask blocks",()=>{(0,_vitest.it)("come out in their own bucket, after the answer",()=>{const e=placed({id:"a1",kind:"confirm",source:"model",change:"Wipe storage"},"call-ui");const{ask:t,afterText:c,nested:a}=(0,_blockPlacement.placeBlocks)([e,grid("ui2")],["c1"]);(0,_vitest.expect)(t.map(s=>s.block.id)).toEqual(["a1"]);(0,_vitest.expect)(c.map(s=>s.block.id)).toEqual(["ui2"]);(0,_vitest.expect)(a.size).toBe(0)})});(0,_vitest.describe)("the answer comes after the prose",()=>{(0,_vitest.it)("puts a model-authored card in the after-text bucket, never before it",()=>{const e=(0,_blockPlacement.placeBlocks)([grid()],["c1"]);(0,_vitest.expect)(e.afterText.map(t=>t.block.id)).toEqual(["ui1"]);(0,_vitest.expect)(e.nested.size).toBe(0)})});
@@ -1,150 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _askBuoyStore = require("./askBuoyStore");
5
- /**
6
- * The queue is a list, and it knows when to hold.
7
- *
8
- * Both rules were written from a defect: the single slot this replaced
9
- * OVERWROTE — type two things mid-turn and the first vanished — and its flush
10
- * ran on `!busy` alone, so a parked message fired into a dead connection after
11
- * an error and was sent as the answer to an open choice block.
12
- */
13
-
14
- (0, _vitest.beforeEach)(() => _askBuoyStore.askBuoyStore.reset());
15
- const texts = () => _askBuoyStore.askBuoyStore.getState().queued.map(q => q.text);
16
- (0, _vitest.describe)("queue", () => {
17
- (0, _vitest.it)("keeps every message, in the order typed", () => {
18
- _askBuoyStore.askBuoyStore.enqueue("then set points to 1500");
19
- _askBuoyStore.askBuoyStore.enqueue("and clear the cart after");
20
- (0, _vitest.expect)(texts()).toEqual(["then set points to 1500", "and clear the cart after"]);
21
- });
22
- (0, _vitest.it)("gives identical requests distinct ids", () => {
23
- const a = _askBuoyStore.askBuoyStore.enqueue("again");
24
- const b = _askBuoyStore.askBuoyStore.enqueue("again");
25
- (0, _vitest.expect)(a.id).not.toBe(b.id);
26
- _askBuoyStore.askBuoyStore.removeQueued(a.id);
27
- (0, _vitest.expect)(texts()).toEqual(["again"]);
28
- });
29
- (0, _vitest.it)("delivers from the front, one at a time", () => {
30
- _askBuoyStore.askBuoyStore.enqueue("one");
31
- _askBuoyStore.askBuoyStore.enqueue("two");
32
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.shiftQueued()?.text).toBe("one");
33
- (0, _vitest.expect)(texts()).toEqual(["two"]);
34
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.shiftQueued()?.text).toBe("two");
35
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.shiftQueued()).toBeUndefined();
36
- });
37
- (0, _vitest.it)("comes back from disk as unsent rows", () => {
38
- const ok = _askBuoyStore.askBuoyStore.hydrate({
39
- messages: [{
40
- id: "m1",
41
- role: "user",
42
- text: "hi",
43
- toolCalls: [],
44
- blocks: []
45
- }],
46
- answers: {},
47
- usage: {
48
- input: 0,
49
- output: 0,
50
- requests: 0
51
- },
52
- queued: [{
53
- id: "q1",
54
- text: "still waiting"
55
- }]
56
- });
57
- (0, _vitest.expect)(ok).toBe(true);
58
- (0, _vitest.expect)(texts()).toEqual(["still waiting"]);
59
- // Idle with nothing wrong — but hydrate itself never sends; the flush
60
- // effect in the hook does, and only once the user is looking.
61
- (0, _vitest.expect)((0, _askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("idle");
62
- });
63
- (0, _vitest.it)("is emptied by a new conversation", () => {
64
- _askBuoyStore.askBuoyStore.enqueue("gone");
65
- _askBuoyStore.askBuoyStore.reset();
66
- (0, _vitest.expect)(texts()).toEqual([]);
67
- });
68
- });
69
- (0, _vitest.describe)("turnPhase", () => {
70
- (0, _vitest.it)("is idle with nothing going on", () => {
71
- (0, _vitest.expect)((0, _askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("idle");
72
- });
73
- (0, _vitest.it)("is running during a turn, and stopping once Stop is pressed", () => {
74
- _askBuoyStore.askBuoyStore.addUser("go");
75
- _askBuoyStore.askBuoyStore.startAssistant();
76
- (0, _vitest.expect)((0, _askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("running");
77
- _askBuoyStore.askBuoyStore.requestStop();
78
- (0, _vitest.expect)((0, _askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("stopping");
79
- });
80
- (0, _vitest.it)("is awaitingApproval while a card is up, even though the turn is busy", () => {
81
- _askBuoyStore.askBuoyStore.addUser("wipe it");
82
- _askBuoyStore.askBuoyStore.startAssistant();
83
- void _askBuoyStore.askBuoyStore.askApproval({
84
- id: "c1",
85
- toolId: "storage",
86
- action: "clearAll",
87
- label: "Clear all saved app data",
88
- reason: "Wipes everything"
89
- });
90
- (0, _vitest.expect)((0, _askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("awaitingApproval");
91
- });
92
- (0, _vitest.it)("is awaitingAnswer after a turn ends on an Ask block", () => {
93
- const id = _askBuoyStore.askBuoyStore.startAssistant();
94
- _askBuoyStore.askBuoyStore.applyEvent(id, {
95
- type: "awaiting-user",
96
- blockId: "b1"
97
- });
98
- _askBuoyStore.askBuoyStore.finishAssistant(id);
99
- (0, _vitest.expect)((0, _askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("awaitingAnswer");
100
- });
101
- });
102
- (0, _vitest.describe)("when the queue holds", () => {
103
- (0, _vitest.it)("delivers when idle and the last turn was fine", () => {
104
- _askBuoyStore.askBuoyStore.addUser("hi");
105
- const id = _askBuoyStore.askBuoyStore.startAssistant();
106
- _askBuoyStore.askBuoyStore.applyEvent(id, {
107
- type: "text",
108
- delta: "Hello."
109
- });
110
- _askBuoyStore.askBuoyStore.finishAssistant(id);
111
- (0, _vitest.expect)((0, _askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toBeNull();
112
- });
113
- (0, _vitest.it)("holds after an error, and says so", () => {
114
- _askBuoyStore.askBuoyStore.addUser("hi");
115
- const id = _askBuoyStore.askBuoyStore.startAssistant();
116
- _askBuoyStore.askBuoyStore.applyEvent(id, {
117
- type: "error",
118
- message: "fetch failed"
119
- });
120
- _askBuoyStore.askBuoyStore.finishAssistant(id);
121
- (0, _vitest.expect)((0, _askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toMatch(/failed/);
122
- });
123
- (0, _vitest.it)("holds while an approval card is up", () => {
124
- _askBuoyStore.askBuoyStore.addUser("wipe");
125
- _askBuoyStore.askBuoyStore.startAssistant();
126
- void _askBuoyStore.askBuoyStore.askApproval({
127
- id: "c1",
128
- toolId: "storage",
129
- action: "clearAll",
130
- label: "Clear all saved app data",
131
- reason: "Wipes everything"
132
- });
133
- (0, _vitest.expect)((0, _askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toMatch(/approval/);
134
- });
135
- (0, _vitest.it)("holds while a question is unanswered — a queued task is not the answer", () => {
136
- const id = _askBuoyStore.askBuoyStore.startAssistant();
137
- _askBuoyStore.askBuoyStore.applyEvent(id, {
138
- type: "awaiting-user",
139
- blockId: "b1"
140
- });
141
- _askBuoyStore.askBuoyStore.finishAssistant(id);
142
- (0, _vitest.expect)((0, _askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toMatch(/question/);
143
- });
144
- (0, _vitest.it)("says nothing while a turn is still running — the queue is simply waiting", () => {
145
- _askBuoyStore.askBuoyStore.addUser("go");
146
- _askBuoyStore.askBuoyStore.startAssistant();
147
- (0, _vitest.expect)((0, _askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toBeNull();
148
- });
149
- });
150
- //# sourceMappingURL=queue.test.js.map
1
+ "use strict";var _vitest=require("vitest");var _askBuoyStore=require("./askBuoyStore");(0,_vitest.beforeEach)(()=>_askBuoyStore.askBuoyStore.reset());const texts=()=>_askBuoyStore.askBuoyStore.getState().queued.map(e=>e.text);(0,_vitest.describe)("queue",()=>{(0,_vitest.it)("keeps every message, in the order typed",()=>{_askBuoyStore.askBuoyStore.enqueue("then set points to 1500");_askBuoyStore.askBuoyStore.enqueue("and clear the cart after");(0,_vitest.expect)(texts()).toEqual(["then set points to 1500","and clear the cart after"])});(0,_vitest.it)("gives identical requests distinct ids",()=>{const e=_askBuoyStore.askBuoyStore.enqueue("again");const t=_askBuoyStore.askBuoyStore.enqueue("again");(0,_vitest.expect)(e.id).not.toBe(t.id);_askBuoyStore.askBuoyStore.removeQueued(e.id);(0,_vitest.expect)(texts()).toEqual(["again"])});(0,_vitest.it)("delivers from the front, one at a time",()=>{_askBuoyStore.askBuoyStore.enqueue("one");_askBuoyStore.askBuoyStore.enqueue("two");(0,_vitest.expect)(_askBuoyStore.askBuoyStore.shiftQueued()?.text).toBe("one");(0,_vitest.expect)(texts()).toEqual(["two"]);(0,_vitest.expect)(_askBuoyStore.askBuoyStore.shiftQueued()?.text).toBe("two");(0,_vitest.expect)(_askBuoyStore.askBuoyStore.shiftQueued()).toBeUndefined()});(0,_vitest.it)("comes back from disk as unsent rows",()=>{const e=_askBuoyStore.askBuoyStore.hydrate({messages:[{id:"m1",role:"user",text:"hi",toolCalls:[],blocks:[]}],answers:{},usage:{input:0,output:0,requests:0},queued:[{id:"q1",text:"still waiting"}]});(0,_vitest.expect)(e).toBe(true);(0,_vitest.expect)(texts()).toEqual(["still waiting"]);(0,_vitest.expect)((0,_askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("idle")});(0,_vitest.it)("is emptied by a new conversation",()=>{_askBuoyStore.askBuoyStore.enqueue("gone");_askBuoyStore.askBuoyStore.reset();(0,_vitest.expect)(texts()).toEqual([])})});(0,_vitest.describe)("turnPhase",()=>{(0,_vitest.it)("is idle with nothing going on",()=>{(0,_vitest.expect)((0,_askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("idle")});(0,_vitest.it)("is running during a turn, and stopping once Stop is pressed",()=>{_askBuoyStore.askBuoyStore.addUser("go");_askBuoyStore.askBuoyStore.startAssistant();(0,_vitest.expect)((0,_askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("running");_askBuoyStore.askBuoyStore.requestStop();(0,_vitest.expect)((0,_askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("stopping")});(0,_vitest.it)("is awaitingApproval while a card is up, even though the turn is busy",()=>{_askBuoyStore.askBuoyStore.addUser("wipe it");_askBuoyStore.askBuoyStore.startAssistant();void _askBuoyStore.askBuoyStore.askApproval({id:"c1",toolId:"storage",action:"clearAll",label:"Clear all saved app data",reason:"Wipes everything"});(0,_vitest.expect)((0,_askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("awaitingApproval")});(0,_vitest.it)("is awaitingAnswer after a turn ends on an Ask block",()=>{const e=_askBuoyStore.askBuoyStore.startAssistant();_askBuoyStore.askBuoyStore.applyEvent(e,{type:"awaiting-user",blockId:"b1"});_askBuoyStore.askBuoyStore.finishAssistant(e);(0,_vitest.expect)((0,_askBuoyStore.turnPhaseOf)(_askBuoyStore.askBuoyStore.getState())).toBe("awaitingAnswer")})});(0,_vitest.describe)("when the queue holds",()=>{(0,_vitest.it)("delivers when idle and the last turn was fine",()=>{_askBuoyStore.askBuoyStore.addUser("hi");const e=_askBuoyStore.askBuoyStore.startAssistant();_askBuoyStore.askBuoyStore.applyEvent(e,{type:"text",delta:"Hello."});_askBuoyStore.askBuoyStore.finishAssistant(e);(0,_vitest.expect)((0,_askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toBeNull()});(0,_vitest.it)("holds after an error, and says so",()=>{_askBuoyStore.askBuoyStore.addUser("hi");const e=_askBuoyStore.askBuoyStore.startAssistant();_askBuoyStore.askBuoyStore.applyEvent(e,{type:"error",message:"fetch failed"});_askBuoyStore.askBuoyStore.finishAssistant(e);(0,_vitest.expect)((0,_askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toMatch(/failed/)});(0,_vitest.it)("holds while an approval card is up",()=>{_askBuoyStore.askBuoyStore.addUser("wipe");_askBuoyStore.askBuoyStore.startAssistant();void _askBuoyStore.askBuoyStore.askApproval({id:"c1",toolId:"storage",action:"clearAll",label:"Clear all saved app data",reason:"Wipes everything"});(0,_vitest.expect)((0,_askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toMatch(/approval/)});(0,_vitest.it)("holds while a question is unanswered \u2014 a queued task is not the answer",()=>{const e=_askBuoyStore.askBuoyStore.startAssistant();_askBuoyStore.askBuoyStore.applyEvent(e,{type:"awaiting-user",blockId:"b1"});_askBuoyStore.askBuoyStore.finishAssistant(e);(0,_vitest.expect)((0,_askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toMatch(/question/)});(0,_vitest.it)("says nothing while a turn is still running \u2014 the queue is simply waiting",()=>{_askBuoyStore.askBuoyStore.addUser("go");_askBuoyStore.askBuoyStore.startAssistant();(0,_vitest.expect)((0,_askBuoyStore.queuePauseReason)(_askBuoyStore.askBuoyStore.getState())).toBeNull()})});
@@ -1,77 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.clearConversation = clearConversation;
7
- exports.resetConversation = resetConversation;
8
- var _askBuoyStore = require("./askBuoyStore");
9
- var _transcriptPersistence = require("./transcriptPersistence");
10
- /**
11
- * "New conversation" — the ONE way a conversation is cleared.
12
- *
13
- * Clearing drops the effect ledger, which is the only undo surface, while the
14
- * agent's changes stay live in the app. So the path that clears has to be the
15
- * path that knows whether undo succeeded — and there used to be two paths
16
- * that did not: the sheet's "Undo, then clear" awaited `revertAll` and reset
17
- * without reading the outcome (two of five reverts fail, the conversation
18
- * clears anyway, two changes stay applied with no record), and the desktop's
19
- * `reset` action skipped the question entirely.
20
- *
21
- * Both now come through here. A failed revert does NOT clear: the caller gets
22
- * the list of what is still applied and clearing becomes a second, explicit
23
- * choice.
24
- */
25
-
26
- /** Clear everything, unconditionally. The caller has already decided. */
27
- function clearConversation() {
28
- // All three, or the conversation this said it had cleared comes straight
29
- // back on the next reload with its undo bar intact.
30
- _askBuoyStore.askBuoyStore.getHeldSession()?.session.reset();
31
- _askBuoyStore.askBuoyStore.reset();
32
- void (0, _transcriptPersistence.clearTranscript)();
33
- }
34
-
35
- /**
36
- * Undo what can be undone, then clear — unless something would not go back.
37
- *
38
- * Refuses while a turn is running: the ledger is being written to, and a
39
- * revert racing a dispatch is how "changed since Ask Buoy wrote it" happens
40
- * to our own write.
41
- */
42
- async function resetConversation(input) {
43
- if (_askBuoyStore.askBuoyStore.getState().busy) {
44
- return {
45
- cleared: false,
46
- reverted: 0,
47
- failed: [{
48
- label: "A turn is running",
49
- error: "Stop it first."
50
- }]
51
- };
52
- }
53
- const ledger = _askBuoyStore.askBuoyStore.getLedger();
54
- if (input.undoFirst && ledger) {
55
- const outcome = await ledger.revertAll(input.dispatch);
56
- if (outcome.failed.length > 0) {
57
- return {
58
- cleared: false,
59
- reverted: outcome.reverted,
60
- failed: outcome.failed
61
- };
62
- }
63
- clearConversation();
64
- return {
65
- cleared: true,
66
- reverted: outcome.reverted,
67
- failed: []
68
- };
69
- }
70
- clearConversation();
71
- return {
72
- cleared: true,
73
- reverted: 0,
74
- failed: []
75
- };
76
- }
77
- //# sourceMappingURL=resetConversation.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.clearConversation=clearConversation;exports.resetConversation=resetConversation;var _askBuoyStore=require("./askBuoyStore");var _transcriptPersistence=require("./transcriptPersistence");function clearConversation(){_askBuoyStore.askBuoyStore.getHeldSession()?.session.reset();_askBuoyStore.askBuoyStore.reset();void(0,_transcriptPersistence.clearTranscript)()}async function resetConversation(r){if(_askBuoyStore.askBuoyStore.getState().busy){return{cleared:false,reverted:0,failed:[{label:"A turn is running",error:"Stop it first."}]}}const t=_askBuoyStore.askBuoyStore.getLedger();if(r.undoFirst&&t){const e=await t.revertAll(r.dispatch);if(e.failed.length>0){return{cleared:false,reverted:e.reverted,failed:e.failed}}clearConversation();return{cleared:true,reverted:e.reverted,failed:[]}}clearConversation();return{cleared:true,reverted:0,failed:[]}}
@@ -1,63 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _askBuoyStore = require("./askBuoyStore");
5
- /**
6
- * Putting an unanswered approval back after a restart.
7
- *
8
- * The rule this encodes: a question the user never answered is not the app's
9
- * to drop. Nothing was tapped, so the change is still waiting as far as they
10
- * know — and a card that vanishes on reload reads as consent nobody gave.
11
- *
12
- * The guards matter as much as the restore. The disk read races the tool
13
- * registry (see the note at the restore site), so it can land late, and an old
14
- * question shoved in front of a live conversation would be worse than losing
15
- * it.
16
- */
17
-
18
- const card = {
19
- id: "c1",
20
- toolId: "zustand",
21
- action: "setState",
22
- label: "Update the Poké Mart bag store",
23
- reason: "This will change the app's state.",
24
- params: {
25
- storeName: "bag"
26
- }
27
- };
28
- (0, _vitest.beforeEach)(() => _askBuoyStore.askBuoyStore.reset());
29
- (0, _vitest.describe)("restorePending", () => {
30
- (0, _vitest.it)("puts the card back on screen", () => {
31
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.restorePending(card)).toBe(true);
32
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending).toMatchObject({
33
- toolId: "zustand",
34
- action: "setState",
35
- params: {
36
- storeName: "bag"
37
- }
38
- });
39
- });
40
- (0, _vitest.it)("marks it restored, so Allow runs the call instead of answering a dead promise", () => {
41
- _askBuoyStore.askBuoyStore.restorePending(card);
42
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending?.restored).toBe(true);
43
- });
44
- (0, _vitest.it)("refuses once a turn is under way", () => {
45
- _askBuoyStore.askBuoyStore.beginTurn();
46
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.restorePending(card)).toBe(false);
47
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending).toBeNull();
48
- });
49
- (0, _vitest.it)("refuses when a live card is already asking", () => {
50
- void _askBuoyStore.askBuoyStore.askApproval(card);
51
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.restorePending({
52
- ...card,
53
- id: "c2"
54
- })).toBe(false);
55
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending?.id).toBe("c1");
56
- });
57
- (0, _vitest.it)("answers without throwing, though nothing is waiting on it", () => {
58
- _askBuoyStore.askBuoyStore.restorePending(card);
59
- (0, _vitest.expect)(() => _askBuoyStore.askBuoyStore.answerApproval(true)).not.toThrow();
60
- (0, _vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending).toBeNull();
61
- });
62
- });
63
- //# sourceMappingURL=restorePending.test.js.map
1
+ "use strict";var _vitest=require("vitest");var _askBuoyStore=require("./askBuoyStore");const card={id:"c1",toolId:"zustand",action:"setState",label:"Update the Pok\xE9 Mart bag store",reason:"This will change the app's state.",params:{storeName:"bag"}};(0,_vitest.beforeEach)(()=>_askBuoyStore.askBuoyStore.reset());(0,_vitest.describe)("restorePending",()=>{(0,_vitest.it)("puts the card back on screen",()=>{(0,_vitest.expect)(_askBuoyStore.askBuoyStore.restorePending(card)).toBe(true);(0,_vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending).toMatchObject({toolId:"zustand",action:"setState",params:{storeName:"bag"}})});(0,_vitest.it)("marks it restored, so Allow runs the call instead of answering a dead promise",()=>{_askBuoyStore.askBuoyStore.restorePending(card);(0,_vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending?.restored).toBe(true)});(0,_vitest.it)("refuses once a turn is under way",()=>{_askBuoyStore.askBuoyStore.beginTurn();(0,_vitest.expect)(_askBuoyStore.askBuoyStore.restorePending(card)).toBe(false);(0,_vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending).toBeNull()});(0,_vitest.it)("refuses when a live card is already asking",()=>{void _askBuoyStore.askBuoyStore.askApproval(card);(0,_vitest.expect)(_askBuoyStore.askBuoyStore.restorePending({...card,id:"c2"})).toBe(false);(0,_vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending?.id).toBe("c1")});(0,_vitest.it)("answers without throwing, though nothing is waiting on it",()=>{_askBuoyStore.askBuoyStore.restorePending(card);(0,_vitest.expect)(()=>_askBuoyStore.askBuoyStore.answerApproval(true)).not.toThrow();(0,_vitest.expect)(_askBuoyStore.askBuoyStore.getState().pending).toBeNull()})});
@@ -1,47 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _agentCore = require("@buoy-gg/agent-core");
5
- /**
6
- * Ids from a RESTORED transcript must never collide with a fresh run's.
7
- *
8
- * The bug this covers, in full: every id counter restarted at 1 with the
9
- * process, which was harmless until the transcript started outliving a reload.
10
- * A restored conversation came back holding `rc1`, `ui1` and `m1`; the next
11
- * turn minted `rc1` again; React saw two children with one key and rendered
12
- * one of them twice while dropping the other. On screen that was the same
13
- * store card appearing twice after a reload.
14
- *
15
- * Simulating a restart in one process is the whole difficulty — the module
16
- * caches its counter. `idFactory` is the seam: a second factory stands in for
17
- * the second run, and the shared RUN_ID is what has to differ between them.
18
- */
19
-
20
- (0, _vitest.describe)("ids across a restart", () => {
21
- (0, _vitest.it)("never reissues an id a restored transcript already holds", () => {
22
- // What a saved transcript carries, from a previous launch.
23
- const restored = ["rcOLDRUN-1", "rcOLDRUN-2", "uiOLDRUN-1", "mOLDRUN-1"];
24
- const rc = (0, _agentCore.idFactory)("rc");
25
- const ui = (0, _agentCore.idFactory)("ui");
26
- const m = (0, _agentCore.idFactory)("m");
27
- const fresh = [rc(), rc(), ui(), m()];
28
- for (const id of fresh) (0, _vitest.expect)(restored).not.toContain(id);
29
- });
30
- (0, _vitest.it)("still counts up within one run", () => {
31
- // The counter is what keeps two blocks in the SAME turn apart.
32
- const rc = (0, _agentCore.idFactory)("rc");
33
- const ids = [rc(), rc(), rc()];
34
- (0, _vitest.expect)(new Set(ids).size).toBe(3);
35
- });
36
- (0, _vitest.it)("keeps two prefixes apart even at the same count", () => {
37
- const rc = (0, _agentCore.idFactory)("rc");
38
- const ui = (0, _agentCore.idFactory)("ui");
39
- (0, _vitest.expect)(rc()).not.toBe(ui());
40
- });
41
- (0, _vitest.it)("stamps a run token that is not a fixed string", () => {
42
- // A constant here would put every install back where it started.
43
- (0, _vitest.expect)(_agentCore.RUN_ID).toMatch(/^[a-z0-9]{4,8}$/);
44
- (0, _vitest.expect)((0, _agentCore.idFactory)("rc")()).toBe(`rc${_agentCore.RUN_ID}-1`);
45
- });
46
- });
47
- //# sourceMappingURL=restoredIds.test.js.map
1
+ "use strict";var _vitest=require("vitest");var _agentCore=require("@buoy-gg/agent-core");(0,_vitest.describe)("ids across a restart",()=>{(0,_vitest.it)("never reissues an id a restored transcript already holds",()=>{const t=["rcOLDRUN-1","rcOLDRUN-2","uiOLDRUN-1","mOLDRUN-1"];const e=(0,_agentCore.idFactory)("rc");const r=(0,_agentCore.idFactory)("ui");const c=(0,_agentCore.idFactory)("m");const o=[e(),e(),r(),c()];for(const s of o)(0,_vitest.expect)(t).not.toContain(s)});(0,_vitest.it)("still counts up within one run",()=>{const t=(0,_agentCore.idFactory)("rc");const e=[t(),t(),t()];(0,_vitest.expect)(new Set(e).size).toBe(3)});(0,_vitest.it)("keeps two prefixes apart even at the same count",()=>{const t=(0,_agentCore.idFactory)("rc");const e=(0,_agentCore.idFactory)("ui");(0,_vitest.expect)(t()).not.toBe(e())});(0,_vitest.it)("stamps a run token that is not a fixed string",()=>{(0,_vitest.expect)(_agentCore.RUN_ID).toMatch(/^[a-z0-9]{4,8}$/);(0,_vitest.expect)((0,_agentCore.idFactory)("rc")()).toBe(`rc${_agentCore.RUN_ID}-1`)})});
@@ -1,54 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.SUGGESTIONS = exports.MAX_SUGGESTIONS = void 0;
7
- exports.pickSuggestions = pickSuggestions;
8
- /**
9
- * The empty state's "try asking" chips, filtered to what will actually work.
10
- *
11
- * The list was static, so a release build offered "Make the next request fail
12
- * with a 500" directly above a line saying simulations need a dev build — and
13
- * the agent then refused the very thing the screen had just suggested. First
14
- * impression: broken. Each chip now says what it needs; the empty state keeps
15
- * the ones this device, build and policy can honour.
16
- *
17
- * Deterministic on purpose: no model call, no navigation, no guessed route
18
- * names or account ids. When the tool registry has not reported yet (it fills
19
- * in a frame or two after open) only the chips that need nothing are shown —
20
- * a short list that grows beats a long one that shrinks.
21
- */
22
-
23
- const SUGGESTIONS = exports.SUGGESTIONS = [{
24
- text: "Why is this screen empty?"
25
- }, {
26
- text: "What did the last few network calls return?",
27
- needs: "network"
28
- }, {
29
- text: "Show me what's saved for this user",
30
- needs: "storage"
31
- }, {
32
- text: "Make the next request to this screen fail with a 500",
33
- needs: "network",
34
- write: true,
35
- devOnly: true
36
- }, {
37
- text: "Who am I signed in as right now?"
38
- }, {
39
- text: "Did anything crash or log an error recently?",
40
- needs: "console"
41
- }];
42
-
43
- /** At most this many chips — the rest of the screen is the point. */
44
- const MAX_SUGGESTIONS = exports.MAX_SUGGESTIONS = 4;
45
- function pickSuggestions(input) {
46
- const known = input.availableToolIds.length > 0;
47
- return SUGGESTIONS.filter(s => {
48
- if (s.write && input.readOnly) return false;
49
- if (s.devOnly && input.isRelease) return false;
50
- if (s.needs) return known && input.availableToolIds.includes(s.needs);
51
- return true;
52
- }).slice(0, MAX_SUGGESTIONS).map(s => s.text);
53
- }
54
- //# sourceMappingURL=suggestions.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SUGGESTIONS=exports.MAX_SUGGESTIONS=void 0;exports.pickSuggestions=pickSuggestions;const SUGGESTIONS=exports.SUGGESTIONS=[{text:"Why is this screen empty?"},{text:"What did the last few network calls return?",needs:"network"},{text:"Show me what's saved for this user",needs:"storage"},{text:"Make the next request to this screen fail with a 500",needs:"network",write:true,devOnly:true},{text:"Who am I signed in as right now?"},{text:"Did anything crash or log an error recently?",needs:"console"}];const MAX_SUGGESTIONS=exports.MAX_SUGGESTIONS=4;function pickSuggestions(t){const r=t.availableToolIds.length>0;return SUGGESTIONS.filter(e=>{if(e.write&&t.readOnly)return false;if(e.devOnly&&t.isRelease)return false;if(e.needs)return r&&t.availableToolIds.includes(e.needs);return true}).slice(0,MAX_SUGGESTIONS).map(e=>e.text)}
@@ -1,58 +1 @@
1
- "use strict";
2
-
3
- var _vitest = require("vitest");
4
- var _suggestions = require("./suggestions");
5
- /**
6
- * Chips promise things; only promise what this device can keep.
7
- */
8
-
9
- const all = ["network", "storage", "console", "query"];
10
- (0, _vitest.describe)("pickSuggestions", () => {
11
- (0, _vitest.it)("offers the simulation only on a dev build that may write", () => {
12
- const dev = (0, _suggestions.pickSuggestions)({
13
- availableToolIds: all,
14
- readOnly: false,
15
- isRelease: false
16
- });
17
- (0, _vitest.expect)(dev).toContain("Make the next request to this screen fail with a 500");
18
- const release = (0, _suggestions.pickSuggestions)({
19
- availableToolIds: all,
20
- readOnly: false,
21
- isRelease: true
22
- });
23
- (0, _vitest.expect)(release).not.toContain("Make the next request to this screen fail with a 500");
24
- const readOnly = (0, _suggestions.pickSuggestions)({
25
- availableToolIds: all,
26
- readOnly: true,
27
- isRelease: false
28
- });
29
- (0, _vitest.expect)(readOnly).not.toContain("Make the next request to this screen fail with a 500");
30
- });
31
- (0, _vitest.it)("drops chips whose tool is not on this device", () => {
32
- const noNetwork = (0, _suggestions.pickSuggestions)({
33
- availableToolIds: ["storage"],
34
- readOnly: false,
35
- isRelease: false
36
- });
37
- (0, _vitest.expect)(noNetwork).not.toContain("What did the last few network calls return?");
38
- (0, _vitest.expect)(noNetwork).toContain("Show me what's saved for this user");
39
- });
40
- (0, _vitest.it)("shows only tool-free chips until the registry has reported", () => {
41
- const early = (0, _suggestions.pickSuggestions)({
42
- availableToolIds: [],
43
- readOnly: false,
44
- isRelease: false
45
- });
46
- (0, _vitest.expect)(early).toEqual(["Why is this screen empty?", "Who am I signed in as right now?"]);
47
- });
48
- (0, _vitest.it)("never exceeds the cap and keeps the order", () => {
49
- const out = (0, _suggestions.pickSuggestions)({
50
- availableToolIds: all,
51
- readOnly: false,
52
- isRelease: false
53
- });
54
- (0, _vitest.expect)(out.length).toBeLessThanOrEqual(_suggestions.MAX_SUGGESTIONS);
55
- (0, _vitest.expect)(out[0]).toBe("Why is this screen empty?");
56
- });
57
- });
58
- //# sourceMappingURL=suggestions.test.js.map
1
+ "use strict";var _vitest=require("vitest");var _suggestions=require("./suggestions");const all=["network","storage","console","query"];(0,_vitest.describe)("pickSuggestions",()=>{(0,_vitest.it)("offers the simulation only on a dev build that may write",()=>{const e=(0,_suggestions.pickSuggestions)({availableToolIds:all,readOnly:false,isRelease:false});(0,_vitest.expect)(e).toContain("Make the next request to this screen fail with a 500");const s=(0,_suggestions.pickSuggestions)({availableToolIds:all,readOnly:false,isRelease:true});(0,_vitest.expect)(s).not.toContain("Make the next request to this screen fail with a 500");const t=(0,_suggestions.pickSuggestions)({availableToolIds:all,readOnly:true,isRelease:false});(0,_vitest.expect)(t).not.toContain("Make the next request to this screen fail with a 500")});(0,_vitest.it)("drops chips whose tool is not on this device",()=>{const e=(0,_suggestions.pickSuggestions)({availableToolIds:["storage"],readOnly:false,isRelease:false});(0,_vitest.expect)(e).not.toContain("What did the last few network calls return?");(0,_vitest.expect)(e).toContain("Show me what's saved for this user")});(0,_vitest.it)("shows only tool-free chips until the registry has reported",()=>{const e=(0,_suggestions.pickSuggestions)({availableToolIds:[],readOnly:false,isRelease:false});(0,_vitest.expect)(e).toEqual(["Why is this screen empty?","Who am I signed in as right now?"])});(0,_vitest.it)("never exceeds the cap and keeps the order",()=>{const e=(0,_suggestions.pickSuggestions)({availableToolIds:all,readOnly:false,isRelease:false});(0,_vitest.expect)(e.length).toBeLessThanOrEqual(_suggestions.MAX_SUGGESTIONS);(0,_vitest.expect)(e[0]).toBe("Why is this screen empty?")})});