@buoy-gg/ask-buoy 7.0.35 → 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.
- package/README.md +73 -15
- package/lib/commonjs/blocks/AskBlocks.js +1 -338
- package/lib/commonjs/blocks/BlockRenderer.js +1 -250
- package/lib/commonjs/blocks/ChromePrototypes.js +1 -514
- package/lib/commonjs/blocks/DataBlocks.js +1 -688
- package/lib/commonjs/blocks/ExtraBlocks.js +1 -1854
- package/lib/commonjs/blocks/MediaBlocks.js +1 -140
- package/lib/commonjs/blocks/ReceiptBlocks.js +1 -586
- package/lib/commonjs/blocks/blockText.js +1 -0
- package/lib/commonjs/blocks/blockText.test.js +1 -0
- package/lib/commonjs/blocks/context.js +1 -42
- package/lib/commonjs/blocks/icons.js +1 -96
- package/lib/commonjs/blocks/index.js +1 -95
- package/lib/commonjs/blocks/listRow.test.js +1 -55
- package/lib/commonjs/blocks/pageState.js +1 -34
- package/lib/commonjs/blocks/pageState.test.js +1 -57
- package/lib/commonjs/blocks/primitives.js +1 -401
- package/lib/commonjs/blocks/primitivesIndex.js +1 -62
- package/lib/commonjs/components/ApprovalCard.js +1 -140
- package/lib/commonjs/components/AskBuoyHeader.js +1 -164
- package/lib/commonjs/components/AskBuoyIcon.js +1 -19
- package/lib/commonjs/components/AskBuoyModal.js +1 -353
- package/lib/commonjs/components/AskBuoySettings.js +1 -69
- package/lib/commonjs/components/ChangesBar.js +1 -211
- package/lib/commonjs/components/Composer.js +1 -175
- package/lib/commonjs/components/EmptyState.js +1 -154
- package/lib/commonjs/components/KeyboardPad.js +1 -0
- package/lib/commonjs/components/Markdown.js +1 -252
- package/lib/commonjs/components/MessageList.js +1 -683
- package/lib/commonjs/components/QueuedMessages.js +1 -0
- package/lib/commonjs/components/ThinkingStrip.js +1 -223
- package/lib/commonjs/components/TypingDots.js +1 -63
- package/lib/commonjs/components/markdownParse.js +1 -0
- package/lib/commonjs/components/markdownParse.test.js +1 -0
- package/lib/commonjs/components/useCopyAction.js +1 -50
- package/lib/commonjs/index.js +1 -252
- package/lib/commonjs/preset.js +1 -90
- package/lib/commonjs/store/activityGroups.js +1 -0
- package/lib/commonjs/store/activityGroups.test.js +1 -0
- package/lib/commonjs/store/askBuoySettings.js +1 -67
- package/lib/commonjs/store/askBuoyStore.js +1 -365
- package/lib/commonjs/store/blockPlacement.js +1 -0
- package/lib/commonjs/store/blockPlacement.test.js +1 -0
- package/lib/commonjs/store/queue.test.js +1 -0
- package/lib/commonjs/store/resetConversation.js +1 -0
- package/lib/commonjs/store/restorePending.test.js +1 -0
- package/lib/commonjs/store/restoredIds.test.js +1 -47
- package/lib/commonjs/store/suggestions.js +1 -0
- package/lib/commonjs/store/suggestions.test.js +1 -0
- package/lib/commonjs/store/systemLine.test.js +1 -0
- package/lib/commonjs/store/ticketPrompt.js +1 -0
- package/lib/commonjs/store/traceText.js +1 -81
- package/lib/commonjs/store/traceText.test.js +1 -112
- package/lib/commonjs/store/transcriptPersistence.js +1 -208
- package/lib/commonjs/store/transcriptPersistence.test.js +1 -185
- package/lib/commonjs/store/turnRendering.test.js +1 -0
- package/lib/commonjs/store/useAskBuoy.js +1 -400
- package/lib/commonjs/store/useAskBuoySettings.js +1 -14
- package/lib/commonjs/sync/askBuoySyncAdapter.js +1 -119
- package/lib/commonjs/sync/askBuoySyncAdapter.test.js +1 -141
- package/lib/commonjs/sync/wire.js +1 -58
- package/lib/commonjs/types.js +1 -6
- package/lib/module/blocks/AskBlocks.js +1 -331
- package/lib/module/blocks/BlockRenderer.js +1 -245
- package/lib/module/blocks/ChromePrototypes.js +1 -503
- package/lib/module/blocks/DataBlocks.js +1 -674
- package/lib/module/blocks/ExtraBlocks.js +1 -1827
- package/lib/module/blocks/MediaBlocks.js +1 -135
- package/lib/module/blocks/ReceiptBlocks.js +1 -574
- package/lib/module/blocks/blockText.js +1 -0
- package/lib/module/blocks/blockText.test.js +1 -0
- package/lib/module/blocks/context.js +1 -35
- package/lib/module/blocks/icons.js +1 -91
- package/lib/module/blocks/index.js +1 -8
- package/lib/module/blocks/listRow.test.js +1 -56
- package/lib/module/blocks/pageState.js +1 -30
- package/lib/module/blocks/pageState.test.js +1 -56
- package/lib/module/blocks/primitives.js +1 -389
- package/lib/module/blocks/primitivesIndex.js +1 -5
- package/lib/module/components/ApprovalCard.js +1 -135
- package/lib/module/components/AskBuoyHeader.js +1 -161
- package/lib/module/components/AskBuoyIcon.js +1 -8
- package/lib/module/components/AskBuoyModal.js +1 -348
- package/lib/module/components/AskBuoySettings.js +1 -64
- package/lib/module/components/ChangesBar.js +1 -206
- package/lib/module/components/Composer.js +1 -170
- package/lib/module/components/EmptyState.js +1 -149
- package/lib/module/components/KeyboardPad.js +1 -0
- package/lib/module/components/Markdown.js +1 -246
- package/lib/module/components/MessageList.js +1 -677
- package/lib/module/components/QueuedMessages.js +1 -0
- package/lib/module/components/ThinkingStrip.js +1 -218
- package/lib/module/components/TypingDots.js +1 -58
- package/lib/module/components/markdownParse.js +1 -0
- package/lib/module/components/markdownParse.test.js +1 -0
- package/lib/module/components/useCopyAction.js +1 -46
- package/lib/module/index.js +1 -34
- package/lib/module/preset.js +1 -73
- package/lib/module/store/activityGroups.js +1 -0
- package/lib/module/store/activityGroups.test.js +1 -0
- package/lib/module/store/askBuoySettings.js +1 -62
- package/lib/module/store/askBuoyStore.js +1 -361
- package/lib/module/store/blockPlacement.js +1 -0
- package/lib/module/store/blockPlacement.test.js +1 -0
- package/lib/module/store/queue.test.js +1 -0
- package/lib/module/store/resetConversation.js +1 -0
- package/lib/module/store/restorePending.test.js +1 -0
- package/lib/module/store/restoredIds.test.js +1 -46
- package/lib/module/store/suggestions.js +1 -0
- package/lib/module/store/suggestions.test.js +1 -0
- package/lib/module/store/systemLine.test.js +1 -0
- package/lib/module/store/ticketPrompt.js +1 -0
- package/lib/module/store/traceText.js +1 -75
- package/lib/module/store/traceText.test.js +1 -111
- package/lib/module/store/transcriptPersistence.js +1 -198
- package/lib/module/store/transcriptPersistence.test.js +1 -184
- package/lib/module/store/turnRendering.test.js +1 -0
- package/lib/module/store/useAskBuoy.js +1 -394
- package/lib/module/store/useAskBuoySettings.js +1 -9
- package/lib/module/sync/askBuoySyncAdapter.js +1 -114
- package/lib/module/sync/askBuoySyncAdapter.test.js +1 -140
- package/lib/module/sync/wire.js +1 -47
- package/lib/module/types.js +1 -4
- package/lib/typescript/blocks/DataBlocks.d.ts +11 -0
- package/lib/typescript/blocks/ExtraBlocks.d.ts +18 -2
- package/lib/typescript/blocks/blockText.d.ts +14 -0
- package/lib/typescript/blocks/blockText.test.d.ts +2 -0
- package/lib/typescript/blocks/primitives.d.ts +16 -1
- package/lib/typescript/components/ApprovalCard.d.ts +9 -1
- package/lib/typescript/components/AskBuoyHeader.d.ts +31 -1
- package/lib/typescript/components/Composer.d.ts +16 -1
- package/lib/typescript/components/EmptyState.d.ts +5 -1
- package/lib/typescript/components/KeyboardPad.d.ts +33 -0
- package/lib/typescript/components/Markdown.d.ts +0 -10
- package/lib/typescript/components/MessageList.d.ts +7 -2
- package/lib/typescript/components/QueuedMessages.d.ts +10 -0
- package/lib/typescript/components/markdownParse.d.ts +49 -0
- package/lib/typescript/components/markdownParse.test.d.ts +2 -0
- package/lib/typescript/preset.d.ts +4 -2
- package/lib/typescript/store/activityGroups.d.ts +29 -0
- package/lib/typescript/store/activityGroups.test.d.ts +2 -0
- package/lib/typescript/store/askBuoySettings.d.ts +22 -0
- package/lib/typescript/store/askBuoyStore.d.ts +174 -9
- package/lib/typescript/store/blockPlacement.d.ts +30 -0
- package/lib/typescript/store/blockPlacement.test.d.ts +2 -0
- package/lib/typescript/store/queue.test.d.ts +2 -0
- package/lib/typescript/store/resetConversation.d.ts +38 -0
- package/lib/typescript/store/restorePending.test.d.ts +2 -0
- package/lib/typescript/store/suggestions.d.ts +32 -0
- package/lib/typescript/store/suggestions.test.d.ts +2 -0
- package/lib/typescript/store/systemLine.test.d.ts +2 -0
- package/lib/typescript/store/ticketPrompt.d.ts +11 -0
- package/lib/typescript/store/transcriptPersistence.d.ts +41 -2
- package/lib/typescript/store/turnRendering.test.d.ts +2 -0
- package/lib/typescript/store/useAskBuoy.d.ts +26 -3
- package/lib/typescript/sync/askBuoySyncAdapter.d.ts +29 -6
- package/package.json +10 -10
- package/lib/commonjs/blocks/AskBlocks.js.map +0 -1
- package/lib/commonjs/blocks/BlockRenderer.js.map +0 -1
- package/lib/commonjs/blocks/ChromePrototypes.js.map +0 -1
- package/lib/commonjs/blocks/DataBlocks.js.map +0 -1
- package/lib/commonjs/blocks/ExtraBlocks.js.map +0 -1
- package/lib/commonjs/blocks/MediaBlocks.js.map +0 -1
- package/lib/commonjs/blocks/ReceiptBlocks.js.map +0 -1
- package/lib/commonjs/blocks/context.js.map +0 -1
- package/lib/commonjs/blocks/icons.js.map +0 -1
- package/lib/commonjs/blocks/index.js.map +0 -1
- package/lib/commonjs/blocks/listRow.test.js.map +0 -1
- package/lib/commonjs/blocks/pageState.js.map +0 -1
- package/lib/commonjs/blocks/pageState.test.js.map +0 -1
- package/lib/commonjs/blocks/primitives.js.map +0 -1
- package/lib/commonjs/blocks/primitivesIndex.js.map +0 -1
- package/lib/commonjs/components/ApprovalCard.js.map +0 -1
- package/lib/commonjs/components/AskBuoyHeader.js.map +0 -1
- package/lib/commonjs/components/AskBuoyIcon.js.map +0 -1
- package/lib/commonjs/components/AskBuoyModal.js.map +0 -1
- package/lib/commonjs/components/AskBuoySettings.js.map +0 -1
- package/lib/commonjs/components/ChangesBar.js.map +0 -1
- package/lib/commonjs/components/Composer.js.map +0 -1
- package/lib/commonjs/components/EmptyState.js.map +0 -1
- package/lib/commonjs/components/Markdown.js.map +0 -1
- package/lib/commonjs/components/MessageList.js.map +0 -1
- package/lib/commonjs/components/ThinkingStrip.js.map +0 -1
- package/lib/commonjs/components/TypingDots.js.map +0 -1
- package/lib/commonjs/components/useCopyAction.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/preset.js.map +0 -1
- package/lib/commonjs/store/askBuoySettings.js.map +0 -1
- package/lib/commonjs/store/askBuoyStore.js.map +0 -1
- package/lib/commonjs/store/restoredIds.test.js.map +0 -1
- package/lib/commonjs/store/traceText.js.map +0 -1
- package/lib/commonjs/store/traceText.test.js.map +0 -1
- package/lib/commonjs/store/transcriptPersistence.js.map +0 -1
- package/lib/commonjs/store/transcriptPersistence.test.js.map +0 -1
- package/lib/commonjs/store/useAskBuoy.js.map +0 -1
- package/lib/commonjs/store/useAskBuoySettings.js.map +0 -1
- package/lib/commonjs/sync/askBuoySyncAdapter.js.map +0 -1
- package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +0 -1
- package/lib/commonjs/sync/wire.js.map +0 -1
- package/lib/commonjs/types.js.map +0 -1
- package/lib/module/blocks/AskBlocks.js.map +0 -1
- package/lib/module/blocks/BlockRenderer.js.map +0 -1
- package/lib/module/blocks/ChromePrototypes.js.map +0 -1
- package/lib/module/blocks/DataBlocks.js.map +0 -1
- package/lib/module/blocks/ExtraBlocks.js.map +0 -1
- package/lib/module/blocks/MediaBlocks.js.map +0 -1
- package/lib/module/blocks/ReceiptBlocks.js.map +0 -1
- package/lib/module/blocks/context.js.map +0 -1
- package/lib/module/blocks/icons.js.map +0 -1
- package/lib/module/blocks/index.js.map +0 -1
- package/lib/module/blocks/listRow.test.js.map +0 -1
- package/lib/module/blocks/pageState.js.map +0 -1
- package/lib/module/blocks/pageState.test.js.map +0 -1
- package/lib/module/blocks/primitives.js.map +0 -1
- package/lib/module/blocks/primitivesIndex.js.map +0 -1
- package/lib/module/components/ApprovalCard.js.map +0 -1
- package/lib/module/components/AskBuoyHeader.js.map +0 -1
- package/lib/module/components/AskBuoyIcon.js.map +0 -1
- package/lib/module/components/AskBuoyModal.js.map +0 -1
- package/lib/module/components/AskBuoySettings.js.map +0 -1
- package/lib/module/components/ChangesBar.js.map +0 -1
- package/lib/module/components/Composer.js.map +0 -1
- package/lib/module/components/EmptyState.js.map +0 -1
- package/lib/module/components/Markdown.js.map +0 -1
- package/lib/module/components/MessageList.js.map +0 -1
- package/lib/module/components/ThinkingStrip.js.map +0 -1
- package/lib/module/components/TypingDots.js.map +0 -1
- package/lib/module/components/useCopyAction.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/preset.js.map +0 -1
- package/lib/module/store/askBuoySettings.js.map +0 -1
- package/lib/module/store/askBuoyStore.js.map +0 -1
- package/lib/module/store/restoredIds.test.js.map +0 -1
- package/lib/module/store/traceText.js.map +0 -1
- package/lib/module/store/traceText.test.js.map +0 -1
- package/lib/module/store/transcriptPersistence.js.map +0 -1
- package/lib/module/store/transcriptPersistence.test.js.map +0 -1
- package/lib/module/store/useAskBuoy.js.map +0 -1
- package/lib/module/store/useAskBuoySettings.js.map +0 -1
- package/lib/module/sync/askBuoySyncAdapter.js.map +0 -1
- package/lib/module/sync/askBuoySyncAdapter.test.js.map +0 -1
- package/lib/module/sync/wire.js.map +0 -1
- package/lib/module/types.js.map +0 -1
- package/lib/typescript/blocks/AskBlocks.d.ts.map +0 -1
- package/lib/typescript/blocks/BlockRenderer.d.ts.map +0 -1
- package/lib/typescript/blocks/ChromePrototypes.d.ts.map +0 -1
- package/lib/typescript/blocks/DataBlocks.d.ts.map +0 -1
- package/lib/typescript/blocks/ExtraBlocks.d.ts.map +0 -1
- package/lib/typescript/blocks/MediaBlocks.d.ts.map +0 -1
- package/lib/typescript/blocks/ReceiptBlocks.d.ts.map +0 -1
- package/lib/typescript/blocks/context.d.ts.map +0 -1
- package/lib/typescript/blocks/icons.d.ts.map +0 -1
- package/lib/typescript/blocks/index.d.ts.map +0 -1
- package/lib/typescript/blocks/listRow.test.d.ts.map +0 -1
- package/lib/typescript/blocks/pageState.d.ts.map +0 -1
- package/lib/typescript/blocks/pageState.test.d.ts.map +0 -1
- package/lib/typescript/blocks/primitives.d.ts.map +0 -1
- package/lib/typescript/blocks/primitivesIndex.d.ts.map +0 -1
- package/lib/typescript/components/ApprovalCard.d.ts.map +0 -1
- package/lib/typescript/components/AskBuoyHeader.d.ts.map +0 -1
- package/lib/typescript/components/AskBuoyIcon.d.ts.map +0 -1
- package/lib/typescript/components/AskBuoyModal.d.ts.map +0 -1
- package/lib/typescript/components/AskBuoySettings.d.ts.map +0 -1
- package/lib/typescript/components/ChangesBar.d.ts.map +0 -1
- package/lib/typescript/components/Composer.d.ts.map +0 -1
- package/lib/typescript/components/EmptyState.d.ts.map +0 -1
- package/lib/typescript/components/Markdown.d.ts.map +0 -1
- package/lib/typescript/components/MessageList.d.ts.map +0 -1
- package/lib/typescript/components/ThinkingStrip.d.ts.map +0 -1
- package/lib/typescript/components/TypingDots.d.ts.map +0 -1
- package/lib/typescript/components/useCopyAction.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/store/askBuoySettings.d.ts.map +0 -1
- package/lib/typescript/store/askBuoyStore.d.ts.map +0 -1
- package/lib/typescript/store/restoredIds.test.d.ts.map +0 -1
- package/lib/typescript/store/traceText.d.ts.map +0 -1
- package/lib/typescript/store/traceText.test.d.ts.map +0 -1
- package/lib/typescript/store/transcriptPersistence.d.ts.map +0 -1
- package/lib/typescript/store/transcriptPersistence.test.d.ts.map +0 -1
- package/lib/typescript/store/useAskBuoy.d.ts.map +0 -1
- package/lib/typescript/store/useAskBuoySettings.d.ts.map +0 -1
- package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +0 -1
- package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +0 -1
- package/lib/typescript/sync/wire.d.ts.map +0 -1
- package/lib/typescript/types.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{Pressable,ScrollView,StyleSheet,Text,View}from"react-native";import{night,X}from"@buoy-gg/shared-ui";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const MAX_LIST_HEIGHT=132;export function QueuedMessages({items:e,paused:t,onEdit:s,onRemove:o}){return 0===e.length?null:_jsxs(View,{style:styles.wrap,testID:"buoy-ask-buoy-queued",children:[_jsx(ScrollView,{style:styles.list,contentContainerStyle:styles.listContent,keyboardShouldPersistTaps:"handled",children:e.map((e,i)=>_jsxs(View,{style:[styles.row,null!==t&&styles.rowPaused],children:[_jsxs(Pressable,{testID:`buoy-ask-buoy-queue-item-${i}`,accessibilityRole:"button",accessibilityLabel:`Edit queued message: ${e.text}`,onPress:()=>s(e.id),style:({pressed:e})=>[styles.rowBody,e&&styles.pressed],children:[_jsx(Text,{style:styles.ordinal,children:0===i?"NEXT":"THEN"}),_jsx(Text,{style:styles.text,numberOfLines:3,children:e.text})]}),_jsx(Pressable,{testID:`buoy-ask-buoy-queue-remove-${i}`,accessibilityRole:"button",accessibilityLabel:"Remove queued message",onPress:()=>o(e.id),hitSlop:8,style:({pressed:e})=>[styles.remove,e&&styles.pressed],children:_jsx(X,{size:11,color:night.color.textTertiary})})]},e.id))}),_jsx(Text,{style:[styles.hint,null!==t&&styles.hintPaused],testID:"buoy-ask-buoy-queue-hint",children:t??"Sends one at a time when this turn finishes · tap to edit"})]})}const styles=StyleSheet.create({wrap:{paddingHorizontal:night.gutter,paddingTop:8,gap:6,backgroundColor:night.color.bg},list:{maxHeight:132},listContent:{gap:6},row:{flexDirection:"row",alignItems:"center",borderRadius:night.radius.row,borderWidth:StyleSheet.hairlineWidth,borderColor:night.color.border,backgroundColor:night.color.surface},rowPaused:{borderColor:night.color.warning},rowBody:{flex:1,flexDirection:"row",alignItems:"center",gap:8,paddingVertical:7,paddingLeft:10},ordinal:{color:night.color.textTertiary,fontSize:9,fontWeight:"700",letterSpacing:.6,width:30},text:{flex:1,color:night.color.textSecondary,fontSize:night.font.caption,lineHeight:17},remove:{width:32,height:32,alignItems:"center",justifyContent:"center"},pressed:{opacity:.7},hint:{color:night.color.textTertiary,fontSize:night.font.micro},hintPaused:{color:night.color.warning}});
|
|
@@ -1,218 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The agent's own working, under an answer, collapsed by default.
|
|
5
|
-
*
|
|
6
|
-
* Collapsed is the whole design constraint. A multi-step turn's reasoning is
|
|
7
|
-
* longer than the answer it produced, and rendered open it pushes the answer —
|
|
8
|
-
* the thing the user came for — off the screen. So the strip is one line until
|
|
9
|
-
* someone wants it, and the summary on that line ("3 steps · 2 thoughts") is
|
|
10
|
-
* enough to tell whether opening it is worth it.
|
|
11
|
-
*
|
|
12
|
-
* Every step is expandable on its own too, because the parameters are the
|
|
13
|
-
* useful part when hunting a bug and the tool name alone is not.
|
|
14
|
-
*/
|
|
15
|
-
import { useState } from "react";
|
|
16
|
-
import { Pressable, StyleSheet, Text, View } from "react-native";
|
|
17
|
-
import { Activity, ChevronDown, ChevronRight, night } from "@buoy-gg/shared-ui";
|
|
18
|
-
import { hasTrace, traceEntries } from "../store/traceText";
|
|
19
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
20
|
-
function StepRow({
|
|
21
|
-
n,
|
|
22
|
-
call
|
|
23
|
-
}) {
|
|
24
|
-
const [open, setOpen] = useState(false);
|
|
25
|
-
const failed = call.status === "failed" || call.status === "refused";
|
|
26
|
-
return /*#__PURE__*/_jsxs(Pressable, {
|
|
27
|
-
onPress: () => setOpen(v => !v),
|
|
28
|
-
accessibilityRole: "button",
|
|
29
|
-
accessibilityState: {
|
|
30
|
-
expanded: open
|
|
31
|
-
},
|
|
32
|
-
style: styles.step,
|
|
33
|
-
children: [/*#__PURE__*/_jsxs(View, {
|
|
34
|
-
style: styles.stepLine,
|
|
35
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
36
|
-
style: styles.stepN,
|
|
37
|
-
children: n
|
|
38
|
-
}), /*#__PURE__*/_jsxs(Text, {
|
|
39
|
-
style: [styles.stepName, failed && styles.stepFailed],
|
|
40
|
-
numberOfLines: 1,
|
|
41
|
-
children: [call.toolId, ".", call.action]
|
|
42
|
-
}), call.durationMs !== undefined ? /*#__PURE__*/_jsxs(Text, {
|
|
43
|
-
style: styles.stepMs,
|
|
44
|
-
children: [call.durationMs, "ms"]
|
|
45
|
-
}) : null, /*#__PURE__*/_jsx(Text, {
|
|
46
|
-
style: [styles.stepStatus, failed && styles.stepFailed],
|
|
47
|
-
numberOfLines: 1,
|
|
48
|
-
children: call.status === "ok" ? call.summary || "done" : call.status
|
|
49
|
-
})]
|
|
50
|
-
}), open ? /*#__PURE__*/_jsxs(View, {
|
|
51
|
-
style: styles.detail,
|
|
52
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
53
|
-
style: styles.detailLabel,
|
|
54
|
-
children: "SENT"
|
|
55
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
56
|
-
style: styles.code,
|
|
57
|
-
selectable: true,
|
|
58
|
-
children: call.params ?? "no parameters"
|
|
59
|
-
}), call.result ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
60
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
61
|
-
style: styles.detailLabel,
|
|
62
|
-
children: "RETURNED"
|
|
63
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
64
|
-
style: styles.code,
|
|
65
|
-
selectable: true,
|
|
66
|
-
children: call.result
|
|
67
|
-
})]
|
|
68
|
-
}) : null]
|
|
69
|
-
}) : null]
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
export function ThinkingStrip({
|
|
73
|
-
message
|
|
74
|
-
}) {
|
|
75
|
-
const [open, setOpen] = useState(false);
|
|
76
|
-
if (!hasTrace(message)) return null;
|
|
77
|
-
const entries = traceEntries(message);
|
|
78
|
-
const steps = entries.filter(e => e.kind === "step").length;
|
|
79
|
-
const thoughts = entries.length - steps;
|
|
80
|
-
const wall = message.startedAt !== undefined && message.endedAt !== undefined ? `${((message.endedAt - message.startedAt) / 1000).toFixed(1)}s` : null;
|
|
81
|
-
const summary = [steps ? `${steps} step${steps === 1 ? "" : "s"}` : null, thoughts ? `${thoughts} thought${thoughts === 1 ? "" : "s"}` : null, wall, message.usage ? `${message.usage.input + message.usage.output} tokens` : null].filter(Boolean).join(" · ");
|
|
82
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
83
|
-
style: styles.wrap,
|
|
84
|
-
testID: "buoy-ask-buoy-thinking",
|
|
85
|
-
children: [/*#__PURE__*/_jsxs(Pressable, {
|
|
86
|
-
testID: "buoy-ask-buoy-thinking-toggle",
|
|
87
|
-
onPress: () => setOpen(v => !v),
|
|
88
|
-
accessibilityRole: "button",
|
|
89
|
-
accessibilityLabel: open ? "Hide agent thinking" : "Show agent thinking",
|
|
90
|
-
accessibilityState: {
|
|
91
|
-
expanded: open
|
|
92
|
-
},
|
|
93
|
-
style: styles.head,
|
|
94
|
-
children: [/*#__PURE__*/_jsx(Activity, {
|
|
95
|
-
size: 12,
|
|
96
|
-
color: night.color.textTertiary
|
|
97
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
98
|
-
style: styles.headText,
|
|
99
|
-
children: summary
|
|
100
|
-
}), open ? /*#__PURE__*/_jsx(ChevronDown, {
|
|
101
|
-
size: 12,
|
|
102
|
-
color: night.color.textTertiary
|
|
103
|
-
}) : /*#__PURE__*/_jsx(ChevronRight, {
|
|
104
|
-
size: 12,
|
|
105
|
-
color: night.color.textTertiary
|
|
106
|
-
})]
|
|
107
|
-
}), open ? /*#__PURE__*/_jsxs(View, {
|
|
108
|
-
style: styles.body,
|
|
109
|
-
children: [entries.map((entry, i) => entry.kind === "thought" ? /*#__PURE__*/_jsx(Text, {
|
|
110
|
-
style: styles.thought,
|
|
111
|
-
selectable: true,
|
|
112
|
-
children: entry.text.trim()
|
|
113
|
-
}, `t${i}`) : /*#__PURE__*/_jsx(StepRow, {
|
|
114
|
-
n: entry.n,
|
|
115
|
-
call: entry.call
|
|
116
|
-
}, entry.call.id)), thoughts === 0 ?
|
|
117
|
-
/*#__PURE__*/
|
|
118
|
-
// Said plainly, because an empty reasoning section reads as broken.
|
|
119
|
-
// Most models report none: Claude thinks by default, gpt-4.1 never.
|
|
120
|
-
_jsx(Text, {
|
|
121
|
-
style: styles.none,
|
|
122
|
-
children: "This model reports no reasoning \u2014 the steps above are the whole trace."
|
|
123
|
-
}) : null]
|
|
124
|
-
}) : null]
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
const styles = StyleSheet.create({
|
|
128
|
-
wrap: {
|
|
129
|
-
marginTop: 8,
|
|
130
|
-
borderRadius: night.radius.badge,
|
|
131
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
132
|
-
borderColor: night.color.separator,
|
|
133
|
-
backgroundColor: night.color.fill,
|
|
134
|
-
overflow: "hidden"
|
|
135
|
-
},
|
|
136
|
-
head: {
|
|
137
|
-
flexDirection: "row",
|
|
138
|
-
alignItems: "center",
|
|
139
|
-
gap: 6,
|
|
140
|
-
paddingHorizontal: 10,
|
|
141
|
-
paddingVertical: 7
|
|
142
|
-
},
|
|
143
|
-
headText: {
|
|
144
|
-
flex: 1,
|
|
145
|
-
color: night.color.textTertiary,
|
|
146
|
-
fontSize: night.font.micro,
|
|
147
|
-
fontWeight: "600"
|
|
148
|
-
},
|
|
149
|
-
body: {
|
|
150
|
-
borderTopWidth: StyleSheet.hairlineWidth,
|
|
151
|
-
borderTopColor: night.color.separator
|
|
152
|
-
},
|
|
153
|
-
thought: {
|
|
154
|
-
color: night.color.textSecondary,
|
|
155
|
-
fontSize: night.font.micro,
|
|
156
|
-
lineHeight: 17,
|
|
157
|
-
fontStyle: "italic",
|
|
158
|
-
paddingHorizontal: 10,
|
|
159
|
-
paddingVertical: 8
|
|
160
|
-
},
|
|
161
|
-
step: {
|
|
162
|
-
paddingHorizontal: 10,
|
|
163
|
-
paddingVertical: 7
|
|
164
|
-
},
|
|
165
|
-
stepLine: {
|
|
166
|
-
flexDirection: "row",
|
|
167
|
-
alignItems: "center",
|
|
168
|
-
gap: 8
|
|
169
|
-
},
|
|
170
|
-
stepN: {
|
|
171
|
-
color: night.color.textTertiary,
|
|
172
|
-
fontSize: night.font.micro,
|
|
173
|
-
width: 14
|
|
174
|
-
},
|
|
175
|
-
stepName: {
|
|
176
|
-
flex: 1,
|
|
177
|
-
color: night.color.textSecondary,
|
|
178
|
-
fontSize: night.font.micro,
|
|
179
|
-
fontWeight: "600"
|
|
180
|
-
},
|
|
181
|
-
stepMs: {
|
|
182
|
-
color: night.color.textTertiary,
|
|
183
|
-
fontSize: night.font.micro
|
|
184
|
-
},
|
|
185
|
-
stepStatus: {
|
|
186
|
-
color: night.color.textTertiary,
|
|
187
|
-
fontSize: night.font.micro,
|
|
188
|
-
maxWidth: 110
|
|
189
|
-
},
|
|
190
|
-
stepFailed: {
|
|
191
|
-
color: night.color.danger
|
|
192
|
-
},
|
|
193
|
-
detail: {
|
|
194
|
-
marginTop: 6,
|
|
195
|
-
marginLeft: 22,
|
|
196
|
-
gap: 3
|
|
197
|
-
},
|
|
198
|
-
detailLabel: {
|
|
199
|
-
color: night.color.textTertiary,
|
|
200
|
-
fontSize: 9,
|
|
201
|
-
fontWeight: "700",
|
|
202
|
-
letterSpacing: 0.5
|
|
203
|
-
},
|
|
204
|
-
code: {
|
|
205
|
-
color: night.color.textSecondary,
|
|
206
|
-
fontSize: night.font.micro,
|
|
207
|
-
lineHeight: 16,
|
|
208
|
-
marginBottom: 3
|
|
209
|
-
},
|
|
210
|
-
none: {
|
|
211
|
-
color: night.color.textTertiary,
|
|
212
|
-
fontSize: night.font.micro,
|
|
213
|
-
fontStyle: "italic",
|
|
214
|
-
paddingHorizontal: 10,
|
|
215
|
-
paddingVertical: 8
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
//# sourceMappingURL=ThinkingStrip.js.map
|
|
1
|
+
"use strict";import{useState}from"react";import{Pressable,StyleSheet,Text,View}from"react-native";import{Activity,ChevronDown,ChevronRight,night}from"@buoy-gg/shared-ui";import{hasTrace,traceEntries}from"../store/traceText";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";function StepRow({n:t,call:e}){const[i,s]=useState(!1),o="failed"===e.status||"refused"===e.status;return _jsxs(Pressable,{onPress:()=>s(t=>!t),accessibilityRole:"button",accessibilityState:{expanded:i},style:styles.step,children:[_jsxs(View,{style:styles.stepLine,children:[_jsx(Text,{style:styles.stepN,children:t}),_jsxs(Text,{style:[styles.stepName,o&&styles.stepFailed],numberOfLines:1,children:[e.toolId,".",e.action]}),void 0!==e.durationMs?_jsxs(Text,{style:styles.stepMs,children:[e.durationMs,"ms"]}):null,_jsx(Text,{style:[styles.stepStatus,o&&styles.stepFailed],numberOfLines:1,children:"ok"===e.status?e.summary||"done":e.status})]}),i?_jsxs(View,{style:styles.detail,children:[_jsx(Text,{style:styles.detailLabel,children:"SENT"}),_jsx(Text,{style:styles.code,selectable:!0,children:e.params??"no parameters"}),e.result?_jsxs(_Fragment,{children:[_jsx(Text,{style:styles.detailLabel,children:"RETURNED"}),_jsx(Text,{style:styles.code,selectable:!0,children:e.result})]}):null]}):null]})}export function ThinkingStrip({message:t}){const[e,i]=useState(!1);if(!hasTrace(t))return null;const s=traceEntries(t),o=s.filter(t=>"step"===t.kind).length,l=s.length-o,r=[o?`${o} step${1===o?"":"s"}`:null,l?`${l} thought${1===l?"":"s"}`:null,void 0!==t.startedAt&&void 0!==t.endedAt?`${((t.endedAt-t.startedAt)/1e3).toFixed(1)}s`:null,t.usage?`${t.usage.input+t.usage.output} tokens`:null].filter(Boolean).join(" · ");return _jsxs(View,{style:styles.wrap,testID:"buoy-ask-buoy-thinking",children:[_jsxs(Pressable,{testID:"buoy-ask-buoy-thinking-toggle",onPress:()=>i(t=>!t),accessibilityRole:"button",accessibilityLabel:e?"Hide agent thinking":"Show agent thinking",accessibilityState:{expanded:e},style:styles.head,children:[_jsx(Activity,{size:12,color:night.color.textTertiary}),_jsx(Text,{style:styles.headText,children:r}),_jsx(e?ChevronDown:ChevronRight,{size:12,color:night.color.textTertiary})]}),e?_jsxs(View,{style:styles.body,children:[s.map((t,e)=>"thought"===t.kind?_jsx(Text,{style:styles.thought,selectable:!0,children:t.text.trim()},`t${e}`):_jsx(StepRow,{n:t.n,call:t.call},t.call.id)),0===l?_jsx(Text,{style:styles.none,children:"This model reports no reasoning — the steps above are the whole trace."}):null]}):null]})}const styles=StyleSheet.create({wrap:{marginTop:8,borderRadius:night.radius.badge,borderWidth:StyleSheet.hairlineWidth,borderColor:night.color.separator,backgroundColor:night.color.fill,overflow:"hidden"},head:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:10,paddingVertical:7},headText:{flex:1,color:night.color.textTertiary,fontSize:night.font.micro,fontWeight:"600"},body:{borderTopWidth:StyleSheet.hairlineWidth,borderTopColor:night.color.separator},thought:{color:night.color.textSecondary,fontSize:night.font.micro,lineHeight:17,fontStyle:"italic",paddingHorizontal:10,paddingVertical:8},step:{paddingHorizontal:10,paddingVertical:7},stepLine:{flexDirection:"row",alignItems:"center",gap:8},stepN:{color:night.color.textTertiary,fontSize:night.font.micro,width:14},stepName:{flex:1,color:night.color.textSecondary,fontSize:night.font.micro,fontWeight:"600"},stepMs:{color:night.color.textTertiary,fontSize:night.font.micro},stepStatus:{color:night.color.textTertiary,fontSize:night.font.micro,maxWidth:110},stepFailed:{color:night.color.danger},detail:{marginTop:6,marginLeft:22,gap:3},detailLabel:{color:night.color.textTertiary,fontSize:9,fontWeight:"700",letterSpacing:.5},code:{color:night.color.textSecondary,fontSize:night.font.micro,lineHeight:16,marginBottom:3},none:{color:night.color.textTertiary,fontSize:night.font.micro,fontStyle:"italic",paddingHorizontal:10,paddingVertical:8}});
|
|
@@ -1,58 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Three pulsing dots — the "it heard you" signal between sending a message
|
|
5
|
-
* and the first streamed token. A static "…" glyph read as a finished (and
|
|
6
|
-
* confusing) answer.
|
|
7
|
-
*
|
|
8
|
-
* Native-driver opacity only, so it costs the JS thread nothing while the
|
|
9
|
-
* stream that replaces it is being parsed.
|
|
10
|
-
*/
|
|
11
|
-
import { useEffect, useRef } from "react";
|
|
12
|
-
import { Animated, Easing, StyleSheet, View } from "react-native";
|
|
13
|
-
import { night } from "@buoy-gg/shared-ui";
|
|
14
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
|
-
export function TypingDots() {
|
|
16
|
-
const dots = useRef([0, 1, 2].map(() => new Animated.Value(0.25))).current;
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
const loops = dots.map((v, i) => Animated.loop(Animated.sequence([Animated.delay(i * 140), Animated.timing(v, {
|
|
19
|
-
toValue: 1,
|
|
20
|
-
duration: 320,
|
|
21
|
-
easing: Easing.inOut(Easing.ease),
|
|
22
|
-
useNativeDriver: true
|
|
23
|
-
}), Animated.timing(v, {
|
|
24
|
-
toValue: 0.25,
|
|
25
|
-
duration: 320,
|
|
26
|
-
easing: Easing.inOut(Easing.ease),
|
|
27
|
-
useNativeDriver: true
|
|
28
|
-
}), Animated.delay((2 - i) * 140)])));
|
|
29
|
-
loops.forEach(l => l.start());
|
|
30
|
-
return () => loops.forEach(l => l.stop());
|
|
31
|
-
}, [dots]);
|
|
32
|
-
return /*#__PURE__*/_jsx(View, {
|
|
33
|
-
style: styles.wrap,
|
|
34
|
-
testID: "buoy-ask-buoy-typing",
|
|
35
|
-
accessibilityLabel: "Thinking",
|
|
36
|
-
children: dots.map((v, i) => /*#__PURE__*/_jsx(Animated.View, {
|
|
37
|
-
style: [styles.dot, {
|
|
38
|
-
opacity: v
|
|
39
|
-
}]
|
|
40
|
-
}, i))
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
const styles = StyleSheet.create({
|
|
44
|
-
wrap: {
|
|
45
|
-
flexDirection: "row",
|
|
46
|
-
alignItems: "center",
|
|
47
|
-
gap: 5,
|
|
48
|
-
paddingVertical: 8,
|
|
49
|
-
paddingHorizontal: 2
|
|
50
|
-
},
|
|
51
|
-
dot: {
|
|
52
|
-
width: 7,
|
|
53
|
-
height: 7,
|
|
54
|
-
borderRadius: 4,
|
|
55
|
-
backgroundColor: night.color.textSecondary
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
//# sourceMappingURL=TypingDots.js.map
|
|
1
|
+
"use strict";import{useEffect,useRef}from"react";import{Animated,Easing,StyleSheet,View}from"react-native";import{night}from"@buoy-gg/shared-ui";import{jsx as _jsx}from"react/jsx-runtime";export function TypingDots(){const e=useRef([0,1,2].map(()=>new Animated.Value(.25))).current;return useEffect(()=>{const t=e.map((e,t)=>Animated.loop(Animated.sequence([Animated.delay(140*t),Animated.timing(e,{toValue:1,duration:320,easing:Easing.inOut(Easing.ease),useNativeDriver:!0}),Animated.timing(e,{toValue:.25,duration:320,easing:Easing.inOut(Easing.ease),useNativeDriver:!0}),Animated.delay(140*(2-t))])));return t.forEach(e=>e.start()),()=>t.forEach(e=>e.stop())},[e]),_jsx(View,{style:styles.wrap,testID:"buoy-ask-buoy-typing",accessibilityLabel:"Thinking",children:e.map((e,t)=>_jsx(Animated.View,{style:[styles.dot,{opacity:e}]},t))})}const styles=StyleSheet.create({wrap:{flexDirection:"row",alignItems:"center",gap:5,paddingVertical:8,paddingHorizontal:2},dot:{width:7,height:7,borderRadius:4,backgroundColor:night.color.textSecondary}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const isTableRow=t=>/^\s*\|.*\|\s*$/.test(t),isTableRule=t=>/^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(t),splitRow=t=>t.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(t=>t.trim()),FENCE=/^\s*```\s*([\w+-]*)\s*$/;export function parseBlocks(t){const e=[];let s=[];const n=()=>{s.length&&e.push({kind:"p",text:s.join(" ")}),s=[]},o=t.split("\n");for(let t=0;t<o.length;t++){const l=o[t].replace(/\s+$/,""),i=FENCE.exec(l);if(i){n();const s=[];let l=t+1,c=!1;for(;l<o.length;){if(/^\s*```\s*$/.test(o[l])){c=!0;break}s.push(o[l]),l++}e.push({kind:"code",lang:i[1]??"",text:s.join("\n"),closed:c}),t=c?l:o.length;continue}if(!l.trim()){n();continue}if(isTableRow(l)&&o[t+1]&&isTableRule(o[t+1])){n();const s=splitRow(l),i=[];let c=t+2;for(;c<o.length&&isTableRow(o[c]);)i.push(splitRow(o[c])),c++;e.push({kind:"table",header:s,rows:i}),t=c-1;continue}const c=/^#{1,6}\s+(.*)$/.exec(l);if(c){n(),e.push({kind:"h",text:c[1]});continue}const r=/^(\s*)([-*•]|\d+[.)])\s+(.*)$/.exec(l);if(r){n();const t=Math.min(2,Math.floor(r[1].length/2)),s=/^\d/.test(r[2])?r[2].replace(")","."):"•";e.push({kind:"li",text:r[3],marker:s,depth:t});continue}s.push(l.trim())}return n(),e}export const TABLE_PREVIEW_ROWS=12;export const TABLE_PREVIEW_COLS=4;export function tableTruncation(t,e){const s=[];return e.length>12&&s.push(`12 of ${e.length} rows`),t.length>4&&s.push(`4 of ${t.length} columns`),s.length?`Showing ${s.join(" · ")}`:null}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{describe,expect,it}from"vitest";import{parseBlocks,tableTruncation}from"./markdownParse";describe("fenced code",()=>{it("keeps newlines and indentation",()=>{const e=parseBlocks('Here:\n```json\n{\n "qty": 14\n}\n```\n— the qty changed.');expect(e.map(e=>e.kind)).toEqual(["p","code","p"]);const t=e[1];expect("code"===t.kind&&t.text).toBe('{\n "qty": 14\n}'),expect("code"===t.kind&&t.lang).toBe("json"),expect("code"===t.kind&&t.closed).toBe(!0)}),it("renders an unclosed fence as code while the stream is still inside it",()=>{const e=parseBlocks("```\nline one\nline two");expect(e).toHaveLength(1);const t=e[0];expect(t.kind).toBe("code"),expect("code"===t.kind&&t.closed).toBe(!1),expect("code"===t.kind&&t.text).toBe("line one\nline two")}),it("does not treat fence contents as lists or tables",()=>{const e=parseBlocks("```\n- not a bullet\n| a | b |\n|---|---|\n```");expect(e).toHaveLength(1),expect(e[0].kind).toBe("code")})}),describe("tables",()=>{const e=(e,t)=>{const n=Array.from({length:t},(e,t)=>`c${t}`),o=Array.from({length:e},(e,t)=>n.map((e,n)=>`r${t}c${n}`));return{header:n,rows:o}};it("says nothing about a table that fits",()=>{const t=e(12,4);expect(tableTruncation(t.header,t.rows)).toBeNull()}),it("names the rows it cut",()=>{const t=e(30,4);expect(tableTruncation(t.header,t.rows)).toBe("Showing 12 of 30 rows")}),it("names the columns it cut",()=>{const t=e(3,6);expect(tableTruncation(t.header,t.rows)).toBe("Showing 4 of 6 columns")}),it("names both when both are cut",()=>{const t=e(30,6);expect(tableTruncation(t.header,t.rows)).toBe("Showing 12 of 30 rows · 4 of 6 columns")}),it("still parses a pipe table from text",()=>{const e=parseBlocks("| Item | Qty |\n|---|---|\n| Charizard | 14 |\n| Blastoise | 2 |");expect(e).toHaveLength(1);const t=e[0];expect("table"===t.kind&&t.header).toEqual(["Item","Qty"]),expect("table"===t.kind&&t.rows).toEqual([["Charizard","14"],["Blastoise","2"]])})}),describe("everything else still works",()=>{it("paragraphs, headings and lists",()=>{const e=parseBlocks("# Title\n\nSome prose\ncontinues.\n\n- one\n - nested\n1. first");expect(e).toEqual([{kind:"h",text:"Title"},{kind:"p",text:"Some prose continues."},{kind:"li",text:"one",marker:"•",depth:0},{kind:"li",text:"nested",marker:"•",depth:1},{kind:"li",text:"first",marker:"1.",depth:0}])})});
|
|
@@ -1,46 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Copy that reports what happened.
|
|
5
|
-
*
|
|
6
|
-
* Both clipboard libraries are OPTIONAL peers, so `copyToClipboard` resolves
|
|
7
|
-
* false in an app that installed neither — a copy button that silently does
|
|
8
|
-
* nothing is worse than no copy button, so that case falls through to the OS
|
|
9
|
-
* share sheet (which also offers Copy) instead of failing quietly.
|
|
10
|
-
*
|
|
11
|
-
* `getText` is read on PRESS, not on render: the whole-transcript callers
|
|
12
|
-
* would otherwise rebuild the transcript on every frame of a streaming answer
|
|
13
|
-
* just to have a string ready for a button nobody tapped.
|
|
14
|
-
*/
|
|
15
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
16
|
-
import { Share } from "react-native";
|
|
17
|
-
import { copyToClipboard } from "@buoy-gg/shared-ui";
|
|
18
|
-
|
|
19
|
-
/** Long enough to notice out of the corner of an eye, short enough not to linger. */
|
|
20
|
-
const COPIED_MS = 1500;
|
|
21
|
-
export function useCopyAction(getText) {
|
|
22
|
-
const [copied, setCopied] = useState(false);
|
|
23
|
-
const timer = useRef(null);
|
|
24
|
-
useEffect(() => () => {
|
|
25
|
-
if (timer.current) clearTimeout(timer.current);
|
|
26
|
-
}, []);
|
|
27
|
-
const copy = useCallback(() => {
|
|
28
|
-
const text = getText();
|
|
29
|
-
void copyToClipboard(text).then(ok => {
|
|
30
|
-
if (!ok) {
|
|
31
|
-
void Share.share({
|
|
32
|
-
message: text
|
|
33
|
-
}).catch(() => {});
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
setCopied(true);
|
|
37
|
-
if (timer.current) clearTimeout(timer.current);
|
|
38
|
-
timer.current = setTimeout(() => setCopied(false), COPIED_MS);
|
|
39
|
-
}).catch(() => {});
|
|
40
|
-
}, [getText]);
|
|
41
|
-
return {
|
|
42
|
-
copied,
|
|
43
|
-
copy
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=useCopyAction.js.map
|
|
1
|
+
"use strict";import{useCallback,useEffect,useRef,useState}from"react";import{Share}from"react-native";import{copyToClipboard}from"@buoy-gg/shared-ui";const COPIED_MS=1500;export function useCopyAction(e){const[t,r]=useState(!1),c=useRef(null);return useEffect(()=>()=>{c.current&&clearTimeout(c.current)},[]),{copied:t,copy:useCallback(()=>{const t=e();copyToClipboard(t).then(e=>{e?(r(!0),c.current&&clearTimeout(c.current),c.current=setTimeout(()=>r(!1),1500)):Share.share({message:t}).catch(()=>{})}).catch(()=>{})},[e])}}
|
package/lib/module/index.js
CHANGED
|
@@ -1,34 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @buoy-gg/ask-buoy — "Ask Buoy".
|
|
5
|
-
*
|
|
6
|
-
* A chat sheet that drives every other Buoy tool on behalf of someone who does
|
|
7
|
-
* not read code. The model runs on the company's own endpoint (see
|
|
8
|
-
* `AskBuoyConfig`), the tool calls go through the same `dispatchToolAction`
|
|
9
|
-
* seam a Scenario step uses, and anything it changes is listed in a bar with an
|
|
10
|
-
* Undo.
|
|
11
|
-
*/
|
|
12
|
-
export { AskBuoyModal } from "./components/AskBuoyModal";
|
|
13
|
-
export { askBuoyToolPreset, createAskBuoyTool, AskBuoyIcon, ASK_BUOY_ICON_COLOR } from "./preset";
|
|
14
|
-
export { askBuoySyncAdapter, ASK_BUOY_ADAPTER_VERSION } from "./sync/askBuoySyncAdapter";
|
|
15
|
-
export { askBuoyStore } from "./store/askBuoyStore";
|
|
16
|
-
export { useAskBuoy, useAskBuoyState } from "./store/useAskBuoy";
|
|
17
|
-
export { redactForWire } from "./sync/wire";
|
|
18
|
-
export { BlockRenderer, BlockHandlersProvider, useBlockHandlers } from "./blocks";
|
|
19
|
-
export { Card as BlockCard, ActionRow as BlockActionRow, ProvenanceBadge } from "./blocks";
|
|
20
|
-
export { MessageActions, ReasoningStrip, ElapsedRow, QueuedComposer, ReloadDivider, Timestamp, EditableUserBubble, LivePill } from "./blocks";
|
|
21
|
-
export { Markdown } from "./components/Markdown";
|
|
22
|
-
// The real transcript pieces, exported so the example app's "chat scenes" page
|
|
23
|
-
// can stage conversations in the actual sheet chrome.
|
|
24
|
-
export { MessageList } from "./components/MessageList";
|
|
25
|
-
export { AskBuoyHeader } from "./components/AskBuoyHeader";
|
|
26
|
-
export { AskBuoySettings } from "./components/AskBuoySettings";
|
|
27
|
-
export { ThinkingStrip } from "./components/ThinkingStrip";
|
|
28
|
-
export { askBuoySettings } from "./store/askBuoySettings";
|
|
29
|
-
export { useAskBuoySettings } from "./store/useAskBuoySettings";
|
|
30
|
-
export { traceEntries, traceToText, hasTrace } from "./store/traceText";
|
|
31
|
-
export { Composer } from "./components/Composer";
|
|
32
|
-
export { ChangesBar } from "./components/ChangesBar";
|
|
33
|
-
export { ApprovalCard } from "./components/ApprovalCard";
|
|
34
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";export{AskBuoyModal}from"./components/AskBuoyModal";export{askBuoyToolPreset,createAskBuoyTool,AskBuoyIcon,ASK_BUOY_ICON_COLOR}from"./preset";export{askBuoySyncAdapter,ASK_BUOY_ADAPTER_VERSION}from"./sync/askBuoySyncAdapter";export{askBuoyStore}from"./store/askBuoyStore";export{useAskBuoy,useAskBuoyState}from"./store/useAskBuoy";export{redactForWire}from"./sync/wire";export{BlockRenderer,BlockHandlersProvider,useBlockHandlers}from"./blocks";export{Card as BlockCard,ActionRow as BlockActionRow,ProvenanceBadge}from"./blocks";export{MessageActions,ReasoningStrip,ElapsedRow,QueuedComposer,ReloadDivider,Timestamp,EditableUserBubble,LivePill}from"./blocks";export{Markdown}from"./components/Markdown";export{MessageList}from"./components/MessageList";export{AskBuoyHeader}from"./components/AskBuoyHeader";export{AskBuoySettings}from"./components/AskBuoySettings";export{ThinkingStrip}from"./components/ThinkingStrip";export{askBuoySettings}from"./store/askBuoySettings";export{useAskBuoySettings}from"./store/useAskBuoySettings";export{traceEntries,traceToText,hasTrace}from"./store/traceText";export{Composer}from"./components/Composer";export{ChangesBar}from"./components/ChangesBar";export{ApprovalCard}from"./components/ApprovalCard";
|
package/lib/module/preset.js
CHANGED
|
@@ -1,73 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The Ask Buoy tool preset.
|
|
5
|
-
*
|
|
6
|
-
* Manual chrome (`component` renders its own JsModal) rather than the
|
|
7
|
-
* declarative `modal` config, because ToolModalShell forwards neither a footer
|
|
8
|
-
* slot nor `initialHeight` — and a chat needs a sticky composer and more than
|
|
9
|
-
* the default 400pt of sheet.
|
|
10
|
-
*
|
|
11
|
-
* The config is closed over at creation time rather than read from a store, so
|
|
12
|
-
* the endpoint and headers come from the app's own code on every render and
|
|
13
|
-
* there is never a copy of them sitting anywhere Buoy persists.
|
|
14
|
-
*/
|
|
15
|
-
import { AskBuoyIcon, ASK_BUOY_ICON_COLOR } from "./components/AskBuoyIcon";
|
|
16
|
-
import { AskBuoyModal } from "./components/AskBuoyModal";
|
|
17
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
|
-
export { AskBuoyIcon, ASK_BUOY_ICON_COLOR };
|
|
19
|
-
export const askBuoyToolPreset = {
|
|
20
|
-
id: "ask-buoy",
|
|
21
|
-
name: "ASK BUOY",
|
|
22
|
-
description: "Ask about this app in plain English",
|
|
23
|
-
slot: "both",
|
|
24
|
-
// Set here rather than in floating-tools-core's `toolColors` map: that map
|
|
25
|
-
// is already missing half the shipped tools, so the web twin falls back to a
|
|
26
|
-
// generic accent for them. A color on the preset is the one place both
|
|
27
|
-
// native and web read.
|
|
28
|
-
color: ASK_BUOY_ICON_COLOR,
|
|
29
|
-
icon: ({
|
|
30
|
-
size,
|
|
31
|
-
color
|
|
32
|
-
}) => /*#__PURE__*/_jsx(AskBuoyIcon, {
|
|
33
|
-
size: size,
|
|
34
|
-
color: color || ASK_BUOY_ICON_COLOR
|
|
35
|
-
}),
|
|
36
|
-
component: AskBuoyModal
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* `endpoint` and `model` are REQUIRED at the type level. This used to extend
|
|
41
|
-
* Partial<AskBuoyConfig> with a cast, so a missing endpoint type-checked and
|
|
42
|
-
* only surfaced as a runtime "not set up yet" — the wrong moment to learn it.
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Wire Ask Buoy to your team's AI endpoint.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* createAskBuoyTool({
|
|
50
|
-
* endpoint: "https://ai.acme.com/v1/messages",
|
|
51
|
-
* model: "claude-opus-5",
|
|
52
|
-
* headers: async () => ({ Authorization: `Bearer ${await auth.getToken()}` }),
|
|
53
|
-
* context: { notes: ["user.rewards.points = loyalty points"] },
|
|
54
|
-
* })
|
|
55
|
-
*/
|
|
56
|
-
export function createAskBuoyTool(config) {
|
|
57
|
-
const {
|
|
58
|
-
name,
|
|
59
|
-
description,
|
|
60
|
-
...rest
|
|
61
|
-
} = config;
|
|
62
|
-
const resolved = rest;
|
|
63
|
-
return {
|
|
64
|
-
...askBuoyToolPreset,
|
|
65
|
-
name: name ?? askBuoyToolPreset.name,
|
|
66
|
-
description: description ?? askBuoyToolPreset.description,
|
|
67
|
-
component: props => /*#__PURE__*/_jsx(AskBuoyModal, {
|
|
68
|
-
...props,
|
|
69
|
-
config: resolved
|
|
70
|
-
})
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=preset.js.map
|
|
1
|
+
"use strict";import{AskBuoyIcon,ASK_BUOY_ICON_COLOR}from"./components/AskBuoyIcon";import{AskBuoyModal}from"./components/AskBuoyModal";import{jsx as _jsx}from"react/jsx-runtime";export{AskBuoyIcon,ASK_BUOY_ICON_COLOR};export const askBuoyToolPreset={id:"ask-buoy",name:"ASK BUOY",description:"Ask about this app in plain English",slot:"both",color:ASK_BUOY_ICON_COLOR,icon:({size:o,slot:s})=>_jsx(AskBuoyIcon,{size:"dial"===s?1.5*o:o}),component:AskBuoyModal};export function createAskBuoyTool(o){const{name:s,description:t,...e}=o,n=e;return{...askBuoyToolPreset,name:s??askBuoyToolPreset.name,description:t??askBuoyToolPreset.description,component:o=>_jsx(AskBuoyModal,{...o,config:n})}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{toolTitle}from"@buoy-gg/agent-core";const foldable=t=>"read"===t.effect&&"ok"===t.status;export function groupCalls(t){const e=[];let o=[];const n=()=>{if(0!==o.length){if(1===o.length)e.push({kind:"call",call:o[0]});else{const t=[...new Set(o.map(t=>toolTitle(t.toolId)))];e.push({kind:"reads",id:o.map(t=>t.id).join("+"),calls:o,label:`Looked at ${joinNatural(t)}`,count:o.length})}o=[]}};for(const l of t)foldable(l)?o.push(l):(n(),e.push({kind:"call",call:l}));return n(),e}function joinNatural(t){return t.length<=1?t[0]??"":2===t.length?`${t[0]} and ${t[1]}`:`${t.slice(0,-1).join(", ")} and ${t[t.length-1]}`}export function turnFooter(t){const e=[];void 0!==t.startedAt&&void 0!==t.endedAt&&t.endedAt>=t.startedAt&&e.push(formatElapsed(t.endedAt-t.startedAt));const o=t.toolCalls.length;if(o>0){e.push(`${o} action${1===o?"":"s"}`);const n=e=>t.toolCalls.filter(t=>t.status===e).length,l=n("failed"),a=n("refused"),s=n("declined"),r=n("stopped");l&&e.push(`${l} failed`),a&&e.push(`${a} refused`),s&&e.push(`${s} declined`),r&&e.push(`${r} not run`)}return e.length?e.join(" · "):null}export function formatElapsed(t){const e=Math.max(0,Math.floor(t/1e3));if(e<60)return`${e}s`;const o=Math.floor(e/60);return o<60?`${o}m ${String(e%60).padStart(2,"0")}s`:`${Math.floor(o/60)}h ${String(o%60).padStart(2,"0")}m`}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{describe,expect,it}from"vitest";import{formatElapsed,groupCalls,turnFooter}from"./activityGroups";const call=(e,t,a,o="ok")=>({id:e,toolId:t,action:"x",label:`${t} ${e}`,status:o,effect:a});describe("groupCalls",()=>{it("leaves a single read as an ordinary row",()=>{const e=groupCalls([call("a","console","read")]);expect(e).toEqual([{kind:"call",call:expect.objectContaining({id:"a"})}])}),it("folds consecutive successful reads and names the tools once each",()=>{const e=groupCalls([call("a","network","read"),call("b","storage","read"),call("c","storage","read")]);expect(e).toHaveLength(1);const t=e[0];expect(t.kind).toBe("reads"),expect("reads"===t.kind&&t.count).toBe(3),expect("reads"===t.kind&&t.label).toBe("Looked at Network and Storage")}),it("never folds a write, and never folds reads across one",()=>{const e=groupCalls([call("a","network","read"),call("b","storage","read"),call("w","zustand","write"),call("c","storage","read"),call("d","console","read")]);expect(e.map(e=>"reads"===e.kind?`reads:${e.count}`:`call:${e.call.id}`)).toEqual(["reads:2","call:w","reads:2"])}),it("keeps failed, refused, declined, stopped and running reads as their own rows",()=>{const e=groupCalls([call("a","network","read"),call("f","storage","read","failed"),call("b","storage","read"),call("r","storage","read","running")]);expect(e.map(e=>e.kind)).toEqual(["call","call","call","call"])})}),describe("turnFooter",()=>{it("reports duration and action count",()=>{expect(turnFooter({startedAt:1e3,endedAt:13e3,toolCalls:[call("a","network","read"),call("b","zustand","write")]})).toBe("12s · 2 actions")}),it("separates the outcomes that were not plain successes",()=>{expect(turnFooter({startedAt:0,endedAt:48e3,toolCalls:[call("a","network","read"),call("b","storage","write","failed"),call("c","storage","destructive","declined"),call("d","storage","write","stopped")]})).toBe("48s · 4 actions · 1 failed · 1 declined · 1 not run")}),it("invents no duration for a note with no start time",()=>{expect(turnFooter({endedAt:5e3,toolCalls:[]})).toBeNull(),expect(turnFooter({endedAt:5e3,toolCalls:[call("a","network","read")]})).toBe("1 action")})}),describe("formatElapsed",()=>{it("is compact",()=>{expect(formatElapsed(4200)).toBe("4s"),expect(formatElapsed(64e3)).toBe("1m 04s"),expect(formatElapsed(372e4)).toBe("1h 02m")})});
|
|
@@ -1,62 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Ask Buoy's own preferences — the things a tester sets on the sheet, not the
|
|
5
|
-
* things a developer sets in `askBuoy={{ … }}`.
|
|
6
|
-
*
|
|
7
|
-
* Module-level and subscribable for the same reason the transcript is: the
|
|
8
|
-
* sheet unmounts whenever the tool is closed or minimised, and a preference
|
|
9
|
-
* that reset on every close would not be a preference.
|
|
10
|
-
*/
|
|
11
|
-
import { definePersistedSetting, devToolsStorageKeys } from "@buoy-gg/shared-ui";
|
|
12
|
-
export const DEFAULT_SETTINGS = {
|
|
13
|
-
showThinking: false
|
|
14
|
-
};
|
|
15
|
-
const store = definePersistedSetting(`${devToolsStorageKeys.base}_ask_buoy_settings`, DEFAULT_SETTINGS, {
|
|
16
|
-
sanitize: merged => ({
|
|
17
|
-
showThinking: merged.showThinking === true
|
|
18
|
-
})
|
|
19
|
-
});
|
|
20
|
-
let current = DEFAULT_SETTINGS;
|
|
21
|
-
let loaded = false;
|
|
22
|
-
const listeners = new Set();
|
|
23
|
-
function emit() {
|
|
24
|
-
for (const fn of listeners) {
|
|
25
|
-
try {
|
|
26
|
-
fn();
|
|
27
|
-
} catch {
|
|
28
|
-
// A throwing subscriber must not take the sheet down.
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export const askBuoySettings = {
|
|
33
|
-
get: () => current,
|
|
34
|
-
subscribe(fn) {
|
|
35
|
-
listeners.add(fn);
|
|
36
|
-
// First subscriber pays for the read; everyone after gets the cached value.
|
|
37
|
-
if (!loaded) {
|
|
38
|
-
loaded = true;
|
|
39
|
-
void store.load().then(value => {
|
|
40
|
-
current = value;
|
|
41
|
-
emit();
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return () => listeners.delete(fn);
|
|
45
|
-
},
|
|
46
|
-
set(key, value) {
|
|
47
|
-
if (current[key] === value) return;
|
|
48
|
-
current = {
|
|
49
|
-
...current,
|
|
50
|
-
[key]: value
|
|
51
|
-
};
|
|
52
|
-
emit();
|
|
53
|
-
void store.save(current);
|
|
54
|
-
},
|
|
55
|
-
/** Tests only — the module cache would otherwise leak between them. */
|
|
56
|
-
reset() {
|
|
57
|
-
current = DEFAULT_SETTINGS;
|
|
58
|
-
loaded = false;
|
|
59
|
-
void store.clear();
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
//# sourceMappingURL=askBuoySettings.js.map
|
|
1
|
+
"use strict";import{definePersistedSetting,devToolsStorageKeys}from"@buoy-gg/shared-ui";export const DEFAULT_SETTINGS={showThinking:!1,bypassApprovals:!1,readOnly:!1};const store=definePersistedSetting(`${devToolsStorageKeys.base}_ask_buoy_settings`,DEFAULT_SETTINGS,{sanitize:e=>({showThinking:!0===e.showThinking,bypassApprovals:!0===e.bypassApprovals,readOnly:!0===e.readOnly})});let current=DEFAULT_SETTINGS,loaded=!1;const listeners=new Set;function emit(){for(const e of listeners)try{e()}catch{}}export const askBuoySettings={get:()=>current,subscribe:e=>(listeners.add(e),loaded||(loaded=!0,store.load().then(e=>{current=e,emit()})),()=>listeners.delete(e)),set(e,s){current[e]!==s&&(current={...current,[e]:s},emit(),store.save(current))},reset(){current=DEFAULT_SETTINGS,loaded=!1,store.clear()}};
|