@bikdotai/bik-component-library 0.0.868-beta.8 → 0.0.868

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 (218) hide show
  1. package/README.md +0 -3
  2. package/dist/cjs/components/agent-builder/constants/tools.js +1 -1
  3. package/dist/cjs/components/agent-builder/constants/tools.js.map +1 -1
  4. package/dist/cjs/components/bik-copilot/BIKCopilot.js +2 -0
  5. package/dist/cjs/components/bik-copilot/BIKCopilot.js.map +1 -0
  6. package/dist/cjs/components/bik-copilot/ControlledCopilot.js +2 -0
  7. package/dist/cjs/components/bik-copilot/ControlledCopilot.js.map +1 -0
  8. package/dist/cjs/components/bik-copilot/ControlledCopilot.styled.js +27 -0
  9. package/dist/cjs/components/bik-copilot/ControlledCopilot.styled.js.map +1 -0
  10. package/dist/cjs/components/bik-copilot/CopilotBall.js +2 -0
  11. package/dist/cjs/components/bik-copilot/CopilotBall.js.map +1 -0
  12. package/dist/cjs/components/bik-copilot/CopilotBall.styled.js +42 -0
  13. package/dist/cjs/components/bik-copilot/CopilotBall.styled.js.map +1 -0
  14. package/dist/cjs/components/bik-copilot/CopilotFeedbackModal.js +2 -0
  15. package/dist/cjs/components/bik-copilot/CopilotFeedbackModal.js.map +1 -0
  16. package/dist/cjs/components/bik-copilot/CopilotFeedbackModal.styled.js +108 -0
  17. package/dist/cjs/components/bik-copilot/CopilotFeedbackModal.styled.js.map +1 -0
  18. package/dist/cjs/components/bik-copilot/CopilotPanel.js +2 -0
  19. package/dist/cjs/components/bik-copilot/CopilotPanel.js.map +1 -0
  20. package/dist/cjs/components/bik-copilot/CopilotPanel.styled.js +534 -0
  21. package/dist/cjs/components/bik-copilot/CopilotPanel.styled.js.map +1 -0
  22. package/dist/cjs/components/bik-copilot/copilotPlacement.js +2 -0
  23. package/dist/cjs/components/bik-copilot/copilotPlacement.js.map +1 -0
  24. package/dist/cjs/components/bik-copilot/copilotRegenerate.js +2 -0
  25. package/dist/cjs/components/bik-copilot/copilotRegenerate.js.map +1 -0
  26. package/dist/cjs/components/bik-copilot/services/copilotDb.js +2 -0
  27. package/dist/cjs/components/bik-copilot/services/copilotDb.js.map +1 -0
  28. package/dist/cjs/components/bik-copilot/services/copilotFeedbackClient.js +2 -0
  29. package/dist/cjs/components/bik-copilot/services/copilotFeedbackClient.js.map +1 -0
  30. package/dist/cjs/components/bik-copilot/services/copilotIcebreakersClient.js +2 -0
  31. package/dist/cjs/components/bik-copilot/services/copilotIcebreakersClient.js.map +1 -0
  32. package/dist/cjs/components/bik-copilot/services/copilotMessagesClient.js +2 -0
  33. package/dist/cjs/components/bik-copilot/services/copilotMessagesClient.js.map +1 -0
  34. package/dist/cjs/components/bik-copilot/services/copilotPageSession.js +2 -0
  35. package/dist/cjs/components/bik-copilot/services/copilotPageSession.js.map +1 -0
  36. package/dist/cjs/components/bik-copilot/services/copilotSseParser.js +7 -0
  37. package/dist/cjs/components/bik-copilot/services/copilotSseParser.js.map +1 -0
  38. package/dist/cjs/components/bik-copilot/services/copilotStreamClient.js +2 -0
  39. package/dist/cjs/components/bik-copilot/services/copilotStreamClient.js.map +1 -0
  40. package/dist/cjs/components/bik-copilot/useCopilotIcebreakers.js +2 -0
  41. package/dist/cjs/components/bik-copilot/useCopilotIcebreakers.js.map +1 -0
  42. package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js +2 -0
  43. package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js.map +1 -0
  44. package/dist/cjs/components/bik-copilot/useDraggableFloater.js +2 -0
  45. package/dist/cjs/components/bik-copilot/useDraggableFloater.js.map +1 -0
  46. package/dist/cjs/components/bik-copilot/utils/markdown.js +4 -0
  47. package/dist/cjs/components/bik-copilot/utils/markdown.js.map +1 -0
  48. package/dist/cjs/components/bik-copilot/utils/toolCtas.js +2 -0
  49. package/dist/cjs/components/bik-copilot/utils/toolCtas.js.map +1 -0
  50. package/dist/cjs/components/button/themes.js +2 -2
  51. package/dist/cjs/components/button/themes.js.map +1 -1
  52. package/dist/cjs/components/datePicker/DatePickerWrapper.js +1 -1
  53. package/dist/cjs/components/datePicker/DatePickerWrapper.js.map +1 -1
  54. package/dist/cjs/index.js +1 -1
  55. package/dist/esm/components/agent-builder/constants/tools.d.ts +1 -0
  56. package/dist/esm/components/agent-builder/constants/tools.js +18 -18
  57. package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
  58. package/dist/esm/components/bik-copilot/BIKCopilot.d.ts +31 -0
  59. package/dist/esm/components/bik-copilot/BIKCopilot.js +118 -0
  60. package/dist/esm/components/bik-copilot/BIKCopilot.js.map +1 -0
  61. package/dist/esm/components/bik-copilot/ControlledCopilot.d.ts +14 -0
  62. package/dist/esm/components/bik-copilot/ControlledCopilot.js +174 -0
  63. package/dist/esm/components/bik-copilot/ControlledCopilot.js.map +1 -0
  64. package/dist/esm/components/bik-copilot/ControlledCopilot.styled.d.ts +7 -0
  65. package/dist/esm/components/bik-copilot/ControlledCopilot.styled.js +31 -0
  66. package/dist/esm/components/bik-copilot/ControlledCopilot.styled.js.map +1 -0
  67. package/dist/esm/components/bik-copilot/CopilotBall.d.ts +13 -0
  68. package/dist/esm/components/bik-copilot/CopilotBall.js +50 -0
  69. package/dist/esm/components/bik-copilot/CopilotBall.js.map +1 -0
  70. package/dist/esm/components/bik-copilot/CopilotBall.styled.d.ts +9 -0
  71. package/dist/esm/components/bik-copilot/CopilotBall.styled.js +46 -0
  72. package/dist/esm/components/bik-copilot/CopilotBall.styled.js.map +1 -0
  73. package/dist/esm/components/bik-copilot/CopilotFeedbackModal.d.ts +29 -0
  74. package/dist/esm/components/bik-copilot/CopilotFeedbackModal.js +73 -0
  75. package/dist/esm/components/bik-copilot/CopilotFeedbackModal.js.map +1 -0
  76. package/dist/esm/components/bik-copilot/CopilotFeedbackModal.styled.d.ts +12 -0
  77. package/dist/esm/components/bik-copilot/CopilotFeedbackModal.styled.js +122 -0
  78. package/dist/esm/components/bik-copilot/CopilotFeedbackModal.styled.js.map +1 -0
  79. package/dist/esm/components/bik-copilot/CopilotPanel.d.ts +9 -0
  80. package/dist/esm/components/bik-copilot/CopilotPanel.js +536 -0
  81. package/dist/esm/components/bik-copilot/CopilotPanel.js.map +1 -0
  82. package/dist/esm/components/bik-copilot/CopilotPanel.styled.d.ts +67 -0
  83. package/dist/esm/components/bik-copilot/CopilotPanel.styled.js +573 -0
  84. package/dist/esm/components/bik-copilot/CopilotPanel.styled.js.map +1 -0
  85. package/dist/esm/components/bik-copilot/copilotPlacement.d.ts +24 -0
  86. package/dist/esm/components/bik-copilot/copilotPlacement.js +38 -0
  87. package/dist/esm/components/bik-copilot/copilotPlacement.js.map +1 -0
  88. package/dist/esm/components/bik-copilot/copilotRegenerate.d.ts +22 -0
  89. package/dist/esm/components/bik-copilot/copilotRegenerate.js +6 -0
  90. package/dist/esm/components/bik-copilot/copilotRegenerate.js.map +1 -0
  91. package/dist/esm/components/bik-copilot/index.d.ts +19 -0
  92. package/dist/esm/components/bik-copilot/model.d.ts +804 -0
  93. package/dist/esm/components/bik-copilot/services/copilotDb.d.ts +90 -0
  94. package/dist/esm/components/bik-copilot/services/copilotDb.js +96 -0
  95. package/dist/esm/components/bik-copilot/services/copilotDb.js.map +1 -0
  96. package/dist/esm/components/bik-copilot/services/copilotFeedbackClient.d.ts +15 -0
  97. package/dist/esm/components/bik-copilot/services/copilotFeedbackClient.js +55 -0
  98. package/dist/esm/components/bik-copilot/services/copilotFeedbackClient.js.map +1 -0
  99. package/dist/esm/components/bik-copilot/services/copilotIcebreakersClient.d.ts +11 -0
  100. package/dist/esm/components/bik-copilot/services/copilotIcebreakersClient.js +54 -0
  101. package/dist/esm/components/bik-copilot/services/copilotIcebreakersClient.js.map +1 -0
  102. package/dist/esm/components/bik-copilot/services/copilotMessagesClient.d.ts +23 -0
  103. package/dist/esm/components/bik-copilot/services/copilotMessagesClient.js +78 -0
  104. package/dist/esm/components/bik-copilot/services/copilotMessagesClient.js.map +1 -0
  105. package/dist/esm/components/bik-copilot/services/copilotPageSession.d.ts +37 -0
  106. package/dist/esm/components/bik-copilot/services/copilotPageSession.js +35 -0
  107. package/dist/esm/components/bik-copilot/services/copilotPageSession.js.map +1 -0
  108. package/dist/esm/components/bik-copilot/services/copilotSseParser.d.ts +22 -0
  109. package/dist/esm/components/bik-copilot/services/copilotSseParser.js +52 -0
  110. package/dist/esm/components/bik-copilot/services/copilotSseParser.js.map +1 -0
  111. package/dist/esm/components/bik-copilot/services/copilotStreamClient.d.ts +35 -0
  112. package/dist/esm/components/bik-copilot/services/copilotStreamClient.js +110 -0
  113. package/dist/esm/components/bik-copilot/services/copilotStreamClient.js.map +1 -0
  114. package/dist/esm/components/bik-copilot/useCopilotIcebreakers.d.ts +17 -0
  115. package/dist/esm/components/bik-copilot/useCopilotIcebreakers.js +60 -0
  116. package/dist/esm/components/bik-copilot/useCopilotIcebreakers.js.map +1 -0
  117. package/dist/esm/components/bik-copilot/useCopilotStreamChat.d.ts +20 -0
  118. package/dist/esm/components/bik-copilot/useCopilotStreamChat.js +377 -0
  119. package/dist/esm/components/bik-copilot/useCopilotStreamChat.js.map +1 -0
  120. package/dist/esm/components/bik-copilot/useDraggableFloater.d.ts +9 -0
  121. package/dist/esm/components/bik-copilot/useDraggableFloater.js +118 -0
  122. package/dist/esm/components/bik-copilot/useDraggableFloater.js.map +1 -0
  123. package/dist/esm/components/bik-copilot/utils/markdown.d.ts +1 -0
  124. package/dist/esm/components/bik-copilot/utils/markdown.js +48 -0
  125. package/dist/esm/components/bik-copilot/utils/markdown.js.map +1 -0
  126. package/dist/esm/components/bik-copilot/utils/toolCtas.d.ts +6 -0
  127. package/dist/esm/components/bik-copilot/utils/toolCtas.js +27 -0
  128. package/dist/esm/components/bik-copilot/utils/toolCtas.js.map +1 -0
  129. package/dist/esm/components/button/themes.js +1 -2
  130. package/dist/esm/components/button/themes.js.map +1 -1
  131. package/dist/esm/components/datePicker/DatePickerWrapper.d.ts +0 -7
  132. package/dist/esm/components/datePicker/DatePickerWrapper.js +64 -66
  133. package/dist/esm/components/datePicker/DatePickerWrapper.js.map +1 -1
  134. package/dist/esm/components/datePicker/index.d.ts +0 -1
  135. package/dist/esm/index.d.ts +1 -3
  136. package/dist/esm/index.js +844 -828
  137. package/dist/esm/index.js.map +1 -1
  138. package/package.json +1 -1
  139. package/dist/cjs/components/chip-selector/ChipSelector.js +0 -2
  140. package/dist/cjs/components/chip-selector/ChipSelector.js.map +0 -1
  141. package/dist/cjs/components/chip-selector/ChipSelector.styled.js +0 -36
  142. package/dist/cjs/components/chip-selector/ChipSelector.styled.js.map +0 -1
  143. package/dist/cjs/components/chip-selector/ChipSelectorGroup.js +0 -2
  144. package/dist/cjs/components/chip-selector/ChipSelectorGroup.js.map +0 -1
  145. package/dist/cjs/components/combo-box/ComboBox.js +0 -2
  146. package/dist/cjs/components/combo-box/ComboBox.js.map +0 -1
  147. package/dist/cjs/components/combo-box/ComboBox.styled.js +0 -33
  148. package/dist/cjs/components/combo-box/ComboBox.styled.js.map +0 -1
  149. package/dist/cjs/components/schedule-builder/RefreshSegmentToggle.js +0 -2
  150. package/dist/cjs/components/schedule-builder/RefreshSegmentToggle.js.map +0 -1
  151. package/dist/cjs/components/schedule-builder/ScheduleBuilder.js +0 -2
  152. package/dist/cjs/components/schedule-builder/ScheduleBuilder.js.map +0 -1
  153. package/dist/cjs/components/schedule-builder/ScheduleBuilder.styled.js +0 -138
  154. package/dist/cjs/components/schedule-builder/ScheduleBuilder.styled.js.map +0 -1
  155. package/dist/cjs/components/schedule-builder/ScheduleEndPicker.js +0 -2
  156. package/dist/cjs/components/schedule-builder/ScheduleEndPicker.js.map +0 -1
  157. package/dist/cjs/components/schedule-builder/ScheduleFrequencyPicker.js +0 -2
  158. package/dist/cjs/components/schedule-builder/ScheduleFrequencyPicker.js.map +0 -1
  159. package/dist/cjs/components/schedule-builder/ScheduleHelper.js +0 -2
  160. package/dist/cjs/components/schedule-builder/ScheduleHelper.js.map +0 -1
  161. package/dist/cjs/components/schedule-builder/SendModeSelector.js +0 -2
  162. package/dist/cjs/components/schedule-builder/SendModeSelector.js.map +0 -1
  163. package/dist/cjs/components/schedule-builder/StartDateTimePicker.js +0 -2
  164. package/dist/cjs/components/schedule-builder/StartDateTimePicker.js.map +0 -1
  165. package/dist/cjs/components/schedule-builder/UpcomingRunsPreview.js +0 -2
  166. package/dist/cjs/components/schedule-builder/UpcomingRunsPreview.js.map +0 -1
  167. package/dist/cjs/components/schedule-builder/model.js +0 -2
  168. package/dist/cjs/components/schedule-builder/model.js.map +0 -1
  169. package/dist/esm/components/chip-selector/ChipSelector.d.ts +0 -9
  170. package/dist/esm/components/chip-selector/ChipSelector.js +0 -27
  171. package/dist/esm/components/chip-selector/ChipSelector.js.map +0 -1
  172. package/dist/esm/components/chip-selector/ChipSelector.styled.d.ts +0 -10
  173. package/dist/esm/components/chip-selector/ChipSelector.styled.js +0 -48
  174. package/dist/esm/components/chip-selector/ChipSelector.styled.js.map +0 -1
  175. package/dist/esm/components/chip-selector/ChipSelectorGroup.d.ts +0 -10
  176. package/dist/esm/components/chip-selector/ChipSelectorGroup.js +0 -48
  177. package/dist/esm/components/chip-selector/ChipSelectorGroup.js.map +0 -1
  178. package/dist/esm/components/chip-selector/index.d.ts +0 -4
  179. package/dist/esm/components/chip-selector/model.d.ts +0 -106
  180. package/dist/esm/components/combo-box/ComboBox.d.ts +0 -15
  181. package/dist/esm/components/combo-box/ComboBox.js +0 -118
  182. package/dist/esm/components/combo-box/ComboBox.js.map +0 -1
  183. package/dist/esm/components/combo-box/ComboBox.styled.d.ts +0 -12
  184. package/dist/esm/components/combo-box/ComboBox.styled.js +0 -40
  185. package/dist/esm/components/combo-box/ComboBox.styled.js.map +0 -1
  186. package/dist/esm/components/combo-box/index.d.ts +0 -3
  187. package/dist/esm/components/combo-box/model.d.ts +0 -55
  188. package/dist/esm/components/schedule-builder/RefreshSegmentToggle.d.ts +0 -22
  189. package/dist/esm/components/schedule-builder/RefreshSegmentToggle.js +0 -31
  190. package/dist/esm/components/schedule-builder/RefreshSegmentToggle.js.map +0 -1
  191. package/dist/esm/components/schedule-builder/ScheduleBuilder.d.ts +0 -88
  192. package/dist/esm/components/schedule-builder/ScheduleBuilder.js +0 -105
  193. package/dist/esm/components/schedule-builder/ScheduleBuilder.js.map +0 -1
  194. package/dist/esm/components/schedule-builder/ScheduleBuilder.styled.d.ts +0 -81
  195. package/dist/esm/components/schedule-builder/ScheduleBuilder.styled.js +0 -168
  196. package/dist/esm/components/schedule-builder/ScheduleBuilder.styled.js.map +0 -1
  197. package/dist/esm/components/schedule-builder/ScheduleEndPicker.d.ts +0 -17
  198. package/dist/esm/components/schedule-builder/ScheduleEndPicker.js +0 -105
  199. package/dist/esm/components/schedule-builder/ScheduleEndPicker.js.map +0 -1
  200. package/dist/esm/components/schedule-builder/ScheduleFrequencyPicker.d.ts +0 -21
  201. package/dist/esm/components/schedule-builder/ScheduleFrequencyPicker.js +0 -136
  202. package/dist/esm/components/schedule-builder/ScheduleFrequencyPicker.js.map +0 -1
  203. package/dist/esm/components/schedule-builder/ScheduleHelper.d.ts +0 -110
  204. package/dist/esm/components/schedule-builder/ScheduleHelper.js +0 -196
  205. package/dist/esm/components/schedule-builder/ScheduleHelper.js.map +0 -1
  206. package/dist/esm/components/schedule-builder/SendModeSelector.d.ts +0 -29
  207. package/dist/esm/components/schedule-builder/SendModeSelector.js +0 -41
  208. package/dist/esm/components/schedule-builder/SendModeSelector.js.map +0 -1
  209. package/dist/esm/components/schedule-builder/StartDateTimePicker.d.ts +0 -51
  210. package/dist/esm/components/schedule-builder/StartDateTimePicker.js +0 -120
  211. package/dist/esm/components/schedule-builder/StartDateTimePicker.js.map +0 -1
  212. package/dist/esm/components/schedule-builder/UpcomingRunsPreview.d.ts +0 -19
  213. package/dist/esm/components/schedule-builder/UpcomingRunsPreview.js +0 -44
  214. package/dist/esm/components/schedule-builder/UpcomingRunsPreview.js.map +0 -1
  215. package/dist/esm/components/schedule-builder/index.d.ts +0 -18
  216. package/dist/esm/components/schedule-builder/model.d.ts +0 -69
  217. package/dist/esm/components/schedule-builder/model.js +0 -8
  218. package/dist/esm/components/schedule-builder/model.js.map +0 -1
@@ -0,0 +1,804 @@
1
+ import { CSSProperties, ReactNode, PointerEvent as ReactPointerEvent } from 'react';
2
+ import { ChatMessage, IceBreaker } from '../bik-chatbot/types';
3
+ /**
4
+ * Corner of the viewport the ball is parked in before the user drags it.
5
+ */
6
+ export type CopilotCorner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
7
+ /**
8
+ * Absolute viewport coordinates (px) of the ball's top-left corner.
9
+ */
10
+ export interface CopilotBallPosition {
11
+ x: number;
12
+ y: number;
13
+ }
14
+ /**
15
+ * Viewport size the ball and panel are positioned against.
16
+ */
17
+ export interface CopilotViewport {
18
+ width: number;
19
+ height: number;
20
+ }
21
+ /**
22
+ * Presentation and behaviour props shared by every copilot entry point.
23
+ */
24
+ export interface CopilotShellProps {
25
+ /**
26
+ * Diameter of the draggable ball in px.
27
+ * @default 56
28
+ */
29
+ ballSize?: number;
30
+ /**
31
+ * Viewport corner the ball starts in. Ignored when `initialPosition` is set.
32
+ * @default 'bottom-right'
33
+ */
34
+ corner?: CopilotCorner;
35
+ /**
36
+ * Distance in px kept between the ball and the viewport edges it is parked
37
+ * against.
38
+ * @default 24
39
+ */
40
+ offset?: number;
41
+ /**
42
+ * Exact starting coordinates of the ball's top-left corner. Takes precedence
43
+ * over `corner` and is clamped into the viewport.
44
+ */
45
+ initialPosition?: CopilotBallPosition;
46
+ /**
47
+ * Allows the user to drag the ball anywhere in the viewport. When `false` the
48
+ * ball stays parked and only acts as a button.
49
+ * @default true
50
+ */
51
+ draggable?: boolean;
52
+ /**
53
+ * Animates the ball back to the nearest left/right edge after a drag ends,
54
+ * keeping the vertical position the user chose.
55
+ * @default true
56
+ */
57
+ snapToEdge?: boolean;
58
+ /** Fired after a drag gesture settles, with the ball's final position. */
59
+ onPositionChange?: (position: CopilotBallPosition) => void;
60
+ /** Icon rendered inside the ball while the panel is closed. */
61
+ ballIcon?: ReactNode;
62
+ /** Icon rendered inside the ball while the panel is open. */
63
+ ballOpenIcon?: ReactNode;
64
+ /**
65
+ * Background of the ball. Accepts any CSS background value, so gradients work.
66
+ * @default COLORS.background.brand
67
+ */
68
+ ballColor?: string;
69
+ /**
70
+ * Stacking order for both the ball and the panel.
71
+ * @default 1200
72
+ */
73
+ zIndex?: number;
74
+ /** Accessible label announced for the ball. */
75
+ ballAriaLabel?: string;
76
+ /**
77
+ * Panel width in px. Shrinks automatically on narrow viewports.
78
+ * @default 400
79
+ */
80
+ panelWidth?: number;
81
+ /**
82
+ * Panel height in px. Shrinks automatically on short viewports.
83
+ * @default 700
84
+ */
85
+ panelHeight?: number;
86
+ /**
87
+ * Gap in px between the ball and the panel.
88
+ * @default 12
89
+ */
90
+ panelGap?: number;
91
+ /**
92
+ * Title shown in the panel header.
93
+ * @default 'Copilot'
94
+ */
95
+ title?: string;
96
+ /** Optional pill rendered next to the title, e.g. `"New"`. */
97
+ badge?: string;
98
+ /** Secondary line rendered under the title. */
99
+ subtitle?: string;
100
+ /** Custom node rendered as the header avatar. */
101
+ avatar?: ReactNode;
102
+ /**
103
+ * Placeholder for the message input.
104
+ * @default 'Write your message...'
105
+ */
106
+ placeholder?: string;
107
+ /**
108
+ * Fine print rendered under the input. Pass an empty string to hide it.
109
+ * @default 'AI can make mistakes, Verify the responses.'
110
+ */
111
+ disclaimer?: string;
112
+ /**
113
+ * Headline of the empty state shown before the first message.
114
+ * @default the `title` value
115
+ */
116
+ emptyStateTitle?: string;
117
+ /**
118
+ * Sub-headline of the empty state shown before the first message.
119
+ * @default 'Here are some things you can try'
120
+ */
121
+ emptyStateSubtitle?: string;
122
+ /**
123
+ * Quick-start prompts shown in the empty state. Clicking one sends it as a
124
+ * user message.
125
+ */
126
+ suggestions?: IceBreaker[];
127
+ /** Fired when a suggestion is clicked, before the message is sent. */
128
+ onSuggestionClick?: (suggestion: IceBreaker) => void;
129
+ /**
130
+ * Shows the reset button in the header. Only rendered when `onRefresh` is
131
+ * also provided.
132
+ * @default true
133
+ */
134
+ showRefresh?: boolean;
135
+ /** Fired when the header reset button is clicked. */
136
+ onRefresh?: () => void;
137
+ onRegenerate?: () => void;
138
+ /**
139
+ * Observes a cast thumbs-up or thumbs-down. Not called when a reader presses
140
+ * the same thumb again to clear it -- there is no "unrated" to report.
141
+ *
142
+ * `BIKCopilot` records the vote itself, so a host only needs this to react to
143
+ * one as well; leaving it unset still records.
144
+ */
145
+ onFeedback?: (messageId: string, vote: CopilotFeedbackVote, detail?: CopilotFeedbackDetail) => void;
146
+ /**
147
+ * Heading of the prompt a thumbs-down opens.
148
+ * @default 'What went wrong?'
149
+ */
150
+ dislikeTitle?: string;
151
+ /**
152
+ * Line under that heading.
153
+ * @default `Help us improve ${title}`
154
+ */
155
+ dislikeSubtitle?: string;
156
+ /**
157
+ * The chips it offers. Their `value` is what reaches the backend, so keep it
158
+ * stable even when the label changes.
159
+ * @default COPILOT_FEEDBACK_REASONS
160
+ */
161
+ dislikeReasons?: CopilotFeedbackReasonOption[];
162
+ /**
163
+ * Placeholder of its note field.
164
+ * @default 'Add a quick note...'
165
+ */
166
+ dislikeNotePlaceholder?: string;
167
+ /**
168
+ * Label of its submit button.
169
+ * @default 'Share feedback'
170
+ */
171
+ dislikeSubmitLabel?: string;
172
+ /**
173
+ * Disables the input and suggestions without hiding them.
174
+ * @default false
175
+ */
176
+ inputDisabled?: boolean;
177
+ /**
178
+ * Label rendered beside the animated dots while a reply is pending. Pass an
179
+ * empty string for dots only.
180
+ * @default 'Thinking'
181
+ */
182
+ thinkingLabel?: string;
183
+ /**
184
+ * Note shown in place of — or under — a reply the reader stopped. Pass an
185
+ * empty string to hide it.
186
+ * @default 'This message was interrupted'
187
+ */
188
+ interruptedLabel?: string;
189
+ /**
190
+ * Caption above the follow-up chips the backend suggests. Pass an empty
191
+ * string to show the chips with no caption.
192
+ * @default 'Follow ups'
193
+ */
194
+ followUpsLabel?: string;
195
+ /**
196
+ * A tool CTA under a reply was clicked (e.g. the support-portal link). The
197
+ * link opens on its own — this is only for analytics.
198
+ */
199
+ onToolCtaClick?: (cta: {
200
+ tool: string;
201
+ url: string;
202
+ }) => void;
203
+ /**
204
+ * Caption shown above the transcript while an older page is being fetched.
205
+ * @default 'Loading earlier messages'
206
+ */
207
+ historyLoadingLabel?: string;
208
+ /**
209
+ * Controls the panel from the outside. When set, the component stops managing
210
+ * its own open state and `onOpenChange` must apply the change.
211
+ */
212
+ open?: boolean;
213
+ /**
214
+ * Whether the panel starts open. Ignored when `open` is provided.
215
+ * @default false
216
+ */
217
+ defaultOpen?: boolean;
218
+ /** Fired whenever the panel is opened or closed. */
219
+ onOpenChange?: (open: boolean) => void;
220
+ /**
221
+ * Closes the panel when the user clicks anywhere outside it.
222
+ * @default false
223
+ */
224
+ closeOnClickOutside?: boolean;
225
+ /** Class applied to the panel. */
226
+ className?: string;
227
+ /** Inline styles merged onto the panel. */
228
+ style?: CSSProperties;
229
+ }
230
+ /**
231
+ * Props for the fully controlled copilot: the host owns the transcript and the
232
+ * send handler, so it works with any backend.
233
+ */
234
+ export interface ControlledCopilotProps extends CopilotShellProps {
235
+ /** Conversation rendered in the panel, oldest message first. */
236
+ messages: CopilotMessage[];
237
+ /** Called with the trimmed message text when the user sends or picks a suggestion. */
238
+ onSendMessage: (message: string) => void;
239
+ /**
240
+ * Renders the thinking indicator and blocks sending while a reply is pending.
241
+ * @default false
242
+ */
243
+ isThinking?: boolean;
244
+ /**
245
+ * True for the whole turn, from send until the answer is complete. Turns the
246
+ * send button into a stop button while `onStop` is provided.
247
+ * @default false
248
+ */
249
+ isStreaming?: boolean;
250
+ /**
251
+ * Called when the reader presses stop. Without it the button stays a send
252
+ * button, since there would be nothing to stop.
253
+ */
254
+ onStop?: () => void;
255
+ /**
256
+ * Offers older messages when the reader scrolls to the top. Without
257
+ * `onLoadOlderMessages` nothing is requested, however this is set.
258
+ * @default false
259
+ */
260
+ hasMoreHistory?: boolean;
261
+ /** Shows the loading row above the transcript. @default false */
262
+ isLoadingHistory?: boolean;
263
+ /**
264
+ * Called when the reader scrolls to the top and there is more history. Fires
265
+ * on scroll, so the handler must tolerate being called again while a page is
266
+ * already on its way.
267
+ */
268
+ onLoadOlderMessages?: () => void;
269
+ /** Error banner rendered above the input. */
270
+ errorMessage?: string;
271
+ }
272
+ /**
273
+ * The assistant persona. The `/bik-ai/copilot-chatbot` and `/bik-ai/copilot-icebreakers`
274
+ * endpoints validate this against their own enum and reject anything else.
275
+ */
276
+ export type CopilotAgent = 'BIK_ASSISTANT_AGENT';
277
+ /** A tool's structured output surfaced to the client, e.g. a support ticket URL. */
278
+ export interface CopilotToolResult {
279
+ /** The tool that produced it, e.g. `"create_jira_ticket"`. */
280
+ tool: string;
281
+ /** Tool-specific data, e.g. `{ url: "https://…/support-portal", summary: "…" }`. */
282
+ data: Record<string, unknown>;
283
+ }
284
+ /**
285
+ * Structured `content` of a `TEXT` event from `/bik-ai/copilot-chatbot`. `STREAM`
286
+ * and `ERROR` carry a bare string; `TEXT` wraps the answer — see
287
+ * `readCopilotEventContent`.
288
+ */
289
+ export interface CopilotAnswerPayload {
290
+ /** The reply itself, as markdown. (Legacy copilot sent this as `message`.) */
291
+ reply?: string;
292
+ /** Legacy field name for the reply text — still read for back-compat. */
293
+ message?: string;
294
+ /** The POD the route resolved to, e.g. `"CAMPAIGN"`. */
295
+ pod?: string;
296
+ /**
297
+ * OpenAI's response id for this turn. Echo it as `previousResponseId` next
298
+ * turn to keep the thread's context.
299
+ */
300
+ lastResponseId?: string;
301
+ /** Structured tool outputs for the client (e.g. a create_jira_ticket URL). */
302
+ toolResults?: CopilotToolResult[];
303
+ /** Suggested next prompts, rendered as chips under the reply. */
304
+ followUps?: string[];
305
+ }
306
+ export interface CopilotStreamEvent {
307
+ /**
308
+ * `STREAM` for an incremental chunk, `TEXT` for the final full message,
309
+ * `ERROR` when the turn failed. `POD` (resolved pod) and `TOOL_RESULT`
310
+ * (a tool's structured output) are informational events the client may act on.
311
+ */
312
+ type: 'STREAM' | 'TEXT' | 'ERROR' | 'POD' | 'TOOL_RESULT' | string;
313
+ /**
314
+ * Chunk text on `STREAM`, the complete answer on `TEXT`, the reason on
315
+ * `ERROR`. `TEXT` wraps it in a `CopilotAnswerPayload`.
316
+ */
317
+ content?: string | CopilotAnswerPayload | Record<string, unknown>;
318
+ /** Server-side id of the message being streamed; stable across its chunks. */
319
+ messageId?: string;
320
+ /**
321
+ * Some backends put the response id at the top level instead of inside the
322
+ * TEXT payload's `lastResponseId`. Read as a fallback so either shape threads.
323
+ */
324
+ responseId?: string;
325
+ storeId?: string;
326
+ sessionId?: string;
327
+ }
328
+ /** Body of one streaming copilot turn (`/bik-ai/copilot-chatbot`). */
329
+ export interface CopilotStreamRequest {
330
+ storeId: string;
331
+ agent: CopilotAgent;
332
+ /** Dashboard route the merchant is on, e.g. `'campaigns/overview'`. */
333
+ route: string;
334
+ /** The merchant's message. Sent to the backend as `user_query`. */
335
+ userPrompt: string;
336
+ sessionId: string;
337
+ /** Omitted on the first turn, then the previous turn's `lastResponseId`. */
338
+ previousResponseId?: string;
339
+ /** Overrides the assistant's server-side system prompt (used verbatim). */
340
+ systemPrompt?: string;
341
+ }
342
+ /** How to reach the endpoint. */
343
+ export interface CopilotTransportOptions {
344
+ /** Origin of the AI backend, e.g. `'http://localhost:5001'`. */
345
+ baseUrl: string;
346
+ /**
347
+ * Path appended to `baseUrl`.
348
+ * @default '/bik-ai/copilot-bikchatbot'
349
+ */
350
+ endpointPath?: string;
351
+ /**
352
+ * Extra headers merged into the request — this is where `bik-referer` goes.
353
+ */
354
+ headers?: Record<string, string>;
355
+ /** Value of the `authorization` header. */
356
+ authToken?: string;
357
+ /**
358
+ * Resolves the `authorization` header per request. Prefer this over
359
+ * `authToken` when the token can be refreshed, since it is read on every turn.
360
+ */
361
+ getAuthToken?: () => string | Promise<string>;
362
+ /** Injectable `fetch`, for tests and for hosts with their own instrumentation. */
363
+ fetchImpl?: typeof fetch;
364
+ /**
365
+ * The signed-in staff member, as an email or a name. Sent with a rating so
366
+ * feedback says who left it; nothing else uses it.
367
+ */
368
+ user?: string;
369
+ }
370
+ export type StreamCopilotChatOptions = CopilotStreamRequest & CopilotTransportOptions;
371
+ /** Options for `fetchCopilotIcebreakers`. */
372
+ export interface FetchCopilotIcebreakersOptions extends Omit<CopilotTransportOptions, 'endpointPath'> {
373
+ /**
374
+ * Path appended to `baseUrl`.
375
+ * @default '/bik-ai/copilot-icebreakers'
376
+ */
377
+ endpointPath?: string;
378
+ agent: CopilotAgent;
379
+ route: string;
380
+ /** Sent as `store_id`. Not used to resolve prompts today, but accepted. */
381
+ storeId?: string;
382
+ signal?: AbortSignal;
383
+ }
384
+ /** What the ice-breaker endpoint answers with. */
385
+ export interface CopilotIcebreakersResult {
386
+ agent: string;
387
+ /** The route the backend actually matched, normalized. */
388
+ route: string;
389
+ /** Human-readable page name behind the matched route, when it has one. */
390
+ pageName?: string;
391
+ /** Empty when no knowledge file covers the route — a valid answer. */
392
+ icebreakers: string[];
393
+ }
394
+ /** Options for `useCopilotIcebreakers`. */
395
+ export interface UseCopilotIcebreakersOptions extends Omit<CopilotTransportOptions, 'endpointPath'> {
396
+ /**
397
+ * Path appended to `baseUrl`.
398
+ * @default '/bik-ai/copilot-icebreakers'
399
+ */
400
+ icebreakersPath?: string;
401
+ /**
402
+ * @default 'BIK_ASSISTANT_AGENT'
403
+ */
404
+ agent?: CopilotAgent;
405
+ /**
406
+ * @default 'campaigns/overview'
407
+ */
408
+ route?: string;
409
+ storeId?: string;
410
+ /**
411
+ * Gates the request. The copilot passes `false` until the panel has been
412
+ * opened, so a merchant who never opens it costs no call.
413
+ * @default true
414
+ */
415
+ enabled?: boolean;
416
+ }
417
+ /** Return value of `useCopilotIcebreakers`. */
418
+ export interface UseCopilotIcebreakersResult {
419
+ /** Prompts as the panel wants them, ready for `suggestions`. */
420
+ icebreakers: IceBreaker[];
421
+ /** Page name behind the matched route, when the backend supplied one. */
422
+ pageName?: string;
423
+ /** The normalized route the backend matched. */
424
+ matchedRoute?: string;
425
+ isLoading: boolean;
426
+ /** Set when the request failed. An empty result is not an error. */
427
+ error?: string;
428
+ /** Refetches for the current agent + route. */
429
+ refresh: () => void;
430
+ }
431
+ /** Callbacks driven by `streamCopilotChat`. */
432
+ export interface CopilotStreamHandlers {
433
+ onEvent: (event: CopilotStreamEvent) => void;
434
+ /** The server closed the stream — the turn is done. */
435
+ onComplete?: () => void;
436
+ onError?: (error: Error) => void;
437
+ onAbort?: () => void;
438
+ }
439
+ /** A chat message, plus the streaming state the copilot needs. */
440
+ export interface CopilotMessage extends ChatMessage {
441
+ /** True while this assistant bubble is still being streamed into. */
442
+ isStreaming?: boolean;
443
+ /** `messageId` of the stream events that produced this bubble. */
444
+ messageId?: string;
445
+ /**
446
+ * True when the reader stopped this turn before the answer finished. Survives
447
+ * a reload, so the transcript still says the reply is incomplete.
448
+ */
449
+ wasInterrupted?: boolean;
450
+ /**
451
+ * Prompts the backend suggests as the next question. Only the newest reply's
452
+ * are offered — older ones stay in the transcript but are not rendered.
453
+ */
454
+ followUps?: string[];
455
+ /**
456
+ * Structured tool outputs for this reply, e.g. the support-portal URL from
457
+ * `create_jira_ticket`. Rendered as action buttons under the bubble by
458
+ * `toolResultCtas`, and kept on the message so they survive a reload.
459
+ */
460
+ toolResults?: CopilotToolResult[];
461
+ }
462
+ /** A button rendered under a reply, resolved from a tool's structured output. */
463
+ export interface CopilotToolCta {
464
+ /** Button label, e.g. `"Raise a ticket"`. */
465
+ label: string;
466
+ /** Where it goes. Only http(s) URLs are surfaced. */
467
+ url: string;
468
+ /** The tool it came from, so a caller can tell them apart. */
469
+ tool: string;
470
+ }
471
+ /**
472
+ * One row of `/bik-ai/copilot-messages`, as the backend serializes it. Mapped
473
+ * onto `CopilotMessage` by `fetchCopilotMessages`.
474
+ */
475
+ export interface CopilotStoredMessageRow {
476
+ message_id?: string;
477
+ session_id?: string;
478
+ /** Page the merchant was on when they sent the prompt, normalized. */
479
+ route?: string | null;
480
+ agent?: string | null;
481
+ /** Who sent it. Read case-insensitively, so the enum can grow. */
482
+ owner?: string;
483
+ message?: string;
484
+ /**
485
+ * When the row was created. Declared as epoch millis, but real responses have
486
+ * also carried a numeric string or an ISO timestamp, so readers coerce it
487
+ * rather than trust the number — see `fetchCopilotMessages`.
488
+ */
489
+ created_at?: number | string;
490
+ createdAt?: number | string;
491
+ /** Staff member the turn belongs to; null on older rows. */
492
+ email?: string | null;
493
+ }
494
+ /** One page of server-side history, newest page first. */
495
+ export interface CopilotMessagesPage {
496
+ /** Oldest first within the page, so it can be prepended as-is. */
497
+ messages: CopilotMessage[];
498
+ page: number;
499
+ pageSize: number;
500
+ /** False once there is nothing older left to fetch. */
501
+ hasMore: boolean;
502
+ }
503
+ /** Options for `fetchCopilotMessages`. */
504
+ export interface FetchCopilotMessagesOptions extends Omit<CopilotTransportOptions, 'endpointPath'> {
505
+ /**
506
+ * Path appended to `baseUrl`.
507
+ * @default '/bik-ai/copilot-messages'
508
+ */
509
+ endpointPath?: string;
510
+ storeId: string;
511
+ sessionId: string;
512
+ /** 1 is the newest page; 2 is the 20 before that. @default 1 */
513
+ page?: number;
514
+ /** @default 20, which is also the cap on what IndexedDB keeps. */
515
+ pageSize?: number;
516
+ signal?: AbortSignal;
517
+ }
518
+ /** A thumbs-up or thumbs-down on one reply. */
519
+ export type CopilotFeedbackVote = 'like' | 'dislike';
520
+ /**
521
+ * One chip in the "what went wrong" modal. `value` is what reaches the backend
522
+ * and what feedback is aggregated by, so it stays stable while `label` is free
523
+ * to be reworded or localised.
524
+ */
525
+ export interface CopilotFeedbackReasonOption {
526
+ value: string;
527
+ label: string;
528
+ }
529
+ /** What a reader chose to share about a reply they rated down. */
530
+ export interface CopilotFeedbackDetail {
531
+ /** Chip values, in the order they were picked. Empty when none were. */
532
+ reasons: string[];
533
+ /** The free-text note, when one was written. */
534
+ comment?: string;
535
+ }
536
+ /** Options for `sendCopilotFeedback`. */
537
+ export interface SendCopilotFeedbackOptions extends Omit<CopilotTransportOptions, 'endpointPath'> {
538
+ /**
539
+ * Path appended to `baseUrl`.
540
+ * @default '/bik-ai/copilot-feedback'
541
+ */
542
+ endpointPath?: string;
543
+ storeId: string;
544
+ sessionId: string;
545
+ /** The reply being rated, as `messageId` on a `CopilotMessage`. */
546
+ messageId: string;
547
+ feedback: CopilotFeedbackVote;
548
+ /** Page the reply was given on, so a rating can be read against its pod. */
549
+ route?: string;
550
+ /** What the reader was shown, so a rating is readable on its own. */
551
+ reply?: string;
552
+ /**
553
+ * Who is rating: the signed-in staff member's email, or their name when the
554
+ * host has no address for them. The backend falls back to the store's login
555
+ * address when this is not sent.
556
+ */
557
+ user?: string;
558
+ /** Chip values explaining a thumbs-down, when the reader picked any. */
559
+ reasons?: string[];
560
+ /** Free-text detail collected alongside the vote, when a host collects any. */
561
+ comment?: string;
562
+ signal?: AbortSignal;
563
+ }
564
+ /** What is persisted in IndexedDB for one conversation. */
565
+ export interface CopilotSessionRecord {
566
+ sessionId: string;
567
+ createdAt: number;
568
+ updatedAt: number;
569
+ /**
570
+ * When this record stops being readable: last write + 24h, restamped on every
571
+ * write. Absent on records written before the TTL existed, which are read as
572
+ * `updatedAt + 24h`.
573
+ */
574
+ expiresAt?: number;
575
+ messages: CopilotMessage[];
576
+ /** Last `responseId` seen, so a reload can continue the same OpenAI thread. */
577
+ previousResponseId?: string;
578
+ storeId?: string;
579
+ agent?: string;
580
+ route?: string;
581
+ }
582
+ /** Options for `useCopilotStreamChat`. */
583
+ export interface UseCopilotStreamChatOptions extends CopilotTransportOptions {
584
+ storeId: string;
585
+ /**
586
+ * The assistant persona.
587
+ * @default 'BIK_ASSISTANT_AGENT'
588
+ */
589
+ agent?: CopilotAgent;
590
+ /**
591
+ * Route the merchant is on; sent every turn, so it can change
592
+ * mid-conversation. The backend resolves the turn's page knowledge from it, so
593
+ * the default is a placeholder to replace with the real route.
594
+ * @default 'campaigns/overview'
595
+ */
596
+ route?: string;
597
+ /**
598
+ * Path of the stored-history endpoint, appended to `baseUrl`.
599
+ * @default '/bik-ai/copilot-messages'
600
+ */
601
+ messagesPath?: string;
602
+ /**
603
+ * Path of the feedback endpoint, appended to `baseUrl`.
604
+ * @default '/bik-ai/copilot-feedback'
605
+ */
606
+ feedbackPath?: string;
607
+ /**
608
+ * Reads older messages back from `/bik-ai/copilot-messages` — page 1 when
609
+ * nothing is cached locally, and the page before that each time the reader
610
+ * scrolls to the top. Turn it off to keep the copilot on local history alone.
611
+ * @default true
612
+ */
613
+ loadHistory?: boolean;
614
+ systemPrompt?: string;
615
+ /**
616
+ * Pins the conversation to a session id. Omit it and the hook restores the
617
+ * last session from IndexedDB, or creates one on first use.
618
+ */
619
+ sessionId?: string;
620
+ /**
621
+ * Persists the transcript and the thread's `responseId` to IndexedDB.
622
+ * @default true
623
+ */
624
+ persist?: boolean;
625
+ /** Fired when a turn fails. The message is also surfaced in `error`. */
626
+ onError?: (error: Error) => void;
627
+ /** Fired once a turn's final `TEXT` event has arrived. */
628
+ onResponseComplete?: (payload: {
629
+ text: string;
630
+ responseId?: string;
631
+ followUps?: string[];
632
+ }) => void;
633
+ /** Fired when the active session id changes, including on restore. */
634
+ onSessionIdChange?: (sessionId: string) => void;
635
+ }
636
+ /** Return value of `useCopilotStreamChat`. */
637
+ export interface UseCopilotStreamChatResult {
638
+ messages: CopilotMessage[];
639
+ /** `null` until the session has been restored or created. */
640
+ sessionId: string | null;
641
+ /** Id threaded into the next turn to keep OpenAI's context. */
642
+ previousResponseId?: string;
643
+ /** True from send until the stream closes. */
644
+ isStreaming: boolean;
645
+ /** True while waiting for the first chunk — what drives the thinking bubble. */
646
+ isThinking: boolean;
647
+ /** True while the transcript is being read back from IndexedDB. */
648
+ isRestoring: boolean;
649
+ /** True while an older page of history is on its way. */
650
+ isLoadingHistory: boolean;
651
+ /** False once the endpoint reports there is nothing older left. */
652
+ hasMoreHistory: boolean;
653
+ error?: string;
654
+ sendMessage: (message: string) => void;
655
+ regenerate: () => void;
656
+ /**
657
+ * Records a thumbs-up or thumbs-down on one reply. Fire-and-forget: a failed
658
+ * post surfaces through `onError` and leaves the transcript alone.
659
+ */
660
+ submitFeedback: (messageId: string, feedback: CopilotFeedbackVote, detail?: CopilotFeedbackDetail) => void;
661
+ /**
662
+ * Fetches the page before the oldest message on screen and prepends it. Safe
663
+ * to call on every scroll event: it no-ops while a page is in flight and once
664
+ * the history runs out.
665
+ */
666
+ loadOlderMessages: () => void;
667
+ /** Aborts the in-flight turn, keeping whatever text already arrived. */
668
+ stopStreaming: () => void;
669
+ /** Starts a fresh session id, clearing the transcript and the thread. */
670
+ startNewConversation: () => void;
671
+ }
672
+ /**
673
+ * Props for the copilot wired to the streaming `/bik-ai/copilot-bikchatbot`
674
+ * endpoint, with IndexedDB-backed history and route-aware ice breakers.
675
+ */
676
+ export interface BIKCopilotProps extends CopilotShellProps, UseCopilotStreamChatOptions {
677
+ /**
678
+ * Path of the ice-breaker endpoint, appended to `baseUrl`.
679
+ * @default '/bik-ai/copilot-icebreakers'
680
+ */
681
+ icebreakersPath?: string;
682
+ /**
683
+ * Loads the route's suggested prompts from `/bik-ai/copilot-icebreakers` and
684
+ * shows them in the empty state. The request only fires once the panel has
685
+ * been opened. Passing `suggestions` explicitly wins over whatever is fetched.
686
+ * @default true
687
+ */
688
+ loadIcebreakers?: boolean;
689
+ }
690
+ /**
691
+ * Props of the presentational panel. Rendered by `ControlledCopilot`, exported so a
692
+ * host can build its own shell around it.
693
+ */
694
+ export interface CopilotPanelProps {
695
+ messages: CopilotMessage[];
696
+ onSend: (message: string) => void;
697
+ onClose: () => void;
698
+ title?: string;
699
+ badge?: string;
700
+ subtitle?: string;
701
+ avatar?: ReactNode;
702
+ placeholder?: string;
703
+ disclaimer?: string;
704
+ emptyStateTitle?: string;
705
+ emptyStateSubtitle?: string;
706
+ suggestions?: IceBreaker[];
707
+ onSuggestionClick?: (suggestion: IceBreaker) => void;
708
+ showRefresh?: boolean;
709
+ onRefresh?: () => void;
710
+ onRegenerate?: () => void;
711
+ onFeedback?: (messageId: string, vote: CopilotFeedbackVote, detail?: CopilotFeedbackDetail) => void;
712
+ dislikeTitle?: string;
713
+ dislikeSubtitle?: string;
714
+ dislikeReasons?: CopilotFeedbackReasonOption[];
715
+ dislikeNotePlaceholder?: string;
716
+ dislikeSubmitLabel?: string;
717
+ isThinking?: boolean;
718
+ thinkingLabel?: string;
719
+ isStreaming?: boolean;
720
+ onStop?: () => void;
721
+ interruptedLabel?: string;
722
+ followUpsLabel?: string;
723
+ onToolCtaClick?: (cta: {
724
+ tool: string;
725
+ url: string;
726
+ }) => void;
727
+ hasMoreHistory?: boolean;
728
+ isLoadingHistory?: boolean;
729
+ onLoadOlderMessages?: () => void;
730
+ historyLoadingLabel?: string;
731
+ inputDisabled?: boolean;
732
+ errorMessage?: string;
733
+ width?: number;
734
+ height?: number;
735
+ className?: string;
736
+ style?: CSSProperties;
737
+ }
738
+ /**
739
+ * Props of the draggable ball. Rendered by `ControlledCopilot`, exported so a host can
740
+ * attach it to something other than the copilot panel.
741
+ */
742
+ export interface CopilotBallProps {
743
+ isOpen: boolean;
744
+ onToggle: () => void;
745
+ position: CopilotBallPosition;
746
+ size: number;
747
+ isDragging: boolean;
748
+ draggable: boolean;
749
+ color: string;
750
+ zIndex: number;
751
+ icon?: ReactNode;
752
+ openIcon?: ReactNode;
753
+ ariaLabel?: string;
754
+ onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;
755
+ onPointerMove: (event: ReactPointerEvent<HTMLElement>) => void;
756
+ onPointerUp: (event: ReactPointerEvent<HTMLElement>) => void;
757
+ onPointerCancel: (event: ReactPointerEvent<HTMLElement>) => void;
758
+ }
759
+ /**
760
+ * Pointer handlers produced by `useDraggableFloater`, spread onto the ball.
761
+ */
762
+ export interface CopilotDragHandlers {
763
+ onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;
764
+ onPointerMove: (event: ReactPointerEvent<HTMLElement>) => void;
765
+ onPointerUp: (event: ReactPointerEvent<HTMLElement>) => void;
766
+ onPointerCancel: (event: ReactPointerEvent<HTMLElement>) => void;
767
+ }
768
+ /**
769
+ * Options accepted by `useDraggableFloater`.
770
+ */
771
+ export interface UseDraggableFloaterOptions {
772
+ /** Diameter of the dragged element in px, used for viewport clamping. */
773
+ size: number;
774
+ /** Corner the element is parked in when no `initialPosition` is given. */
775
+ corner: CopilotCorner;
776
+ /** Distance kept from the viewport edges the element is parked against. */
777
+ offset: number;
778
+ /** Whether drag gestures are accepted at all. */
779
+ enabled: boolean;
780
+ /** Whether the element returns to the nearest horizontal edge on release. */
781
+ snapToEdge: boolean;
782
+ /** Exact starting coordinates, clamped into the viewport. */
783
+ initialPosition?: CopilotBallPosition;
784
+ /** Fired once a drag gesture settles. */
785
+ onPositionChange?: (position: CopilotBallPosition) => void;
786
+ }
787
+ /**
788
+ * Return value of `useDraggableFloater`.
789
+ */
790
+ export interface UseDraggableFloaterResult {
791
+ /** Current top-left coordinates of the element. */
792
+ position: CopilotBallPosition;
793
+ /** True while a gesture has moved past the drag threshold. */
794
+ isDragging: boolean;
795
+ /** Latest known viewport size, updated on resize. */
796
+ viewport: CopilotViewport;
797
+ /** Handlers to spread onto the dragged element. */
798
+ dragHandlers: CopilotDragHandlers;
799
+ /**
800
+ * Reads and clears the "the last gesture was a drag" flag. Call it at the top
801
+ * of the element's click handler so a drag does not also fire a click.
802
+ */
803
+ shouldIgnoreClick: () => boolean;
804
+ }