@bikdotai/bik-component-library 0.0.863-beta.1 → 0.0.863-beta.3

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 (102) hide show
  1. package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
  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/agent-builder/utils/sourceIcons.js.map +1 -1
  5. package/dist/cjs/index.js +1 -1
  6. package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
  7. package/dist/esm/components/agent-builder/constants/tools.d.ts +6 -5
  8. package/dist/esm/components/agent-builder/constants/tools.js +24 -21
  9. package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
  10. package/dist/esm/components/agent-builder/utils/sourceIcons.d.ts +4 -0
  11. package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -1
  12. package/dist/esm/index.d.ts +0 -1
  13. package/dist/esm/index.js +782 -832
  14. package/dist/esm/index.js.map +1 -1
  15. package/package.json +1 -1
  16. package/dist/cjs/components/bik-copilot/BIKCopilot.js +0 -2
  17. package/dist/cjs/components/bik-copilot/BIKCopilot.js.map +0 -1
  18. package/dist/cjs/components/bik-copilot/ControlledCopilot.js +0 -2
  19. package/dist/cjs/components/bik-copilot/ControlledCopilot.js.map +0 -1
  20. package/dist/cjs/components/bik-copilot/ControlledCopilot.styled.js +0 -27
  21. package/dist/cjs/components/bik-copilot/ControlledCopilot.styled.js.map +0 -1
  22. package/dist/cjs/components/bik-copilot/CopilotBall.js +0 -2
  23. package/dist/cjs/components/bik-copilot/CopilotBall.js.map +0 -1
  24. package/dist/cjs/components/bik-copilot/CopilotBall.styled.js +0 -42
  25. package/dist/cjs/components/bik-copilot/CopilotBall.styled.js.map +0 -1
  26. package/dist/cjs/components/bik-copilot/CopilotPanel.js +0 -2
  27. package/dist/cjs/components/bik-copilot/CopilotPanel.js.map +0 -1
  28. package/dist/cjs/components/bik-copilot/CopilotPanel.styled.js +0 -460
  29. package/dist/cjs/components/bik-copilot/CopilotPanel.styled.js.map +0 -1
  30. package/dist/cjs/components/bik-copilot/copilotPlacement.js +0 -2
  31. package/dist/cjs/components/bik-copilot/copilotPlacement.js.map +0 -1
  32. package/dist/cjs/components/bik-copilot/services/copilotDb.js +0 -2
  33. package/dist/cjs/components/bik-copilot/services/copilotDb.js.map +0 -1
  34. package/dist/cjs/components/bik-copilot/services/copilotIcebreakersClient.js +0 -2
  35. package/dist/cjs/components/bik-copilot/services/copilotIcebreakersClient.js.map +0 -1
  36. package/dist/cjs/components/bik-copilot/services/copilotMessagesClient.js +0 -2
  37. package/dist/cjs/components/bik-copilot/services/copilotMessagesClient.js.map +0 -1
  38. package/dist/cjs/components/bik-copilot/services/copilotPageSession.js +0 -2
  39. package/dist/cjs/components/bik-copilot/services/copilotPageSession.js.map +0 -1
  40. package/dist/cjs/components/bik-copilot/services/copilotSseParser.js +0 -7
  41. package/dist/cjs/components/bik-copilot/services/copilotSseParser.js.map +0 -1
  42. package/dist/cjs/components/bik-copilot/services/copilotStreamClient.js +0 -2
  43. package/dist/cjs/components/bik-copilot/services/copilotStreamClient.js.map +0 -1
  44. package/dist/cjs/components/bik-copilot/useCopilotIcebreakers.js +0 -2
  45. package/dist/cjs/components/bik-copilot/useCopilotIcebreakers.js.map +0 -1
  46. package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js +0 -2
  47. package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js.map +0 -1
  48. package/dist/cjs/components/bik-copilot/useDraggableFloater.js +0 -2
  49. package/dist/cjs/components/bik-copilot/useDraggableFloater.js.map +0 -1
  50. package/dist/esm/components/bik-copilot/BIKCopilot.d.ts +0 -32
  51. package/dist/esm/components/bik-copilot/BIKCopilot.js +0 -114
  52. package/dist/esm/components/bik-copilot/BIKCopilot.js.map +0 -1
  53. package/dist/esm/components/bik-copilot/ControlledCopilot.d.ts +0 -14
  54. package/dist/esm/components/bik-copilot/ControlledCopilot.js +0 -170
  55. package/dist/esm/components/bik-copilot/ControlledCopilot.js.map +0 -1
  56. package/dist/esm/components/bik-copilot/ControlledCopilot.styled.d.ts +0 -7
  57. package/dist/esm/components/bik-copilot/ControlledCopilot.styled.js +0 -31
  58. package/dist/esm/components/bik-copilot/ControlledCopilot.styled.js.map +0 -1
  59. package/dist/esm/components/bik-copilot/CopilotBall.d.ts +0 -13
  60. package/dist/esm/components/bik-copilot/CopilotBall.js +0 -50
  61. package/dist/esm/components/bik-copilot/CopilotBall.js.map +0 -1
  62. package/dist/esm/components/bik-copilot/CopilotBall.styled.d.ts +0 -9
  63. package/dist/esm/components/bik-copilot/CopilotBall.styled.js +0 -46
  64. package/dist/esm/components/bik-copilot/CopilotBall.styled.js.map +0 -1
  65. package/dist/esm/components/bik-copilot/CopilotPanel.d.ts +0 -9
  66. package/dist/esm/components/bik-copilot/CopilotPanel.js +0 -379
  67. package/dist/esm/components/bik-copilot/CopilotPanel.js.map +0 -1
  68. package/dist/esm/components/bik-copilot/CopilotPanel.styled.d.ts +0 -64
  69. package/dist/esm/components/bik-copilot/CopilotPanel.styled.js +0 -496
  70. package/dist/esm/components/bik-copilot/CopilotPanel.styled.js.map +0 -1
  71. package/dist/esm/components/bik-copilot/copilotPlacement.d.ts +0 -24
  72. package/dist/esm/components/bik-copilot/copilotPlacement.js +0 -38
  73. package/dist/esm/components/bik-copilot/copilotPlacement.js.map +0 -1
  74. package/dist/esm/components/bik-copilot/index.d.ts +0 -16
  75. package/dist/esm/components/bik-copilot/model.d.ts +0 -674
  76. package/dist/esm/components/bik-copilot/services/copilotDb.d.ts +0 -90
  77. package/dist/esm/components/bik-copilot/services/copilotDb.js +0 -96
  78. package/dist/esm/components/bik-copilot/services/copilotDb.js.map +0 -1
  79. package/dist/esm/components/bik-copilot/services/copilotIcebreakersClient.d.ts +0 -11
  80. package/dist/esm/components/bik-copilot/services/copilotIcebreakersClient.js +0 -54
  81. package/dist/esm/components/bik-copilot/services/copilotIcebreakersClient.js.map +0 -1
  82. package/dist/esm/components/bik-copilot/services/copilotMessagesClient.d.ts +0 -23
  83. package/dist/esm/components/bik-copilot/services/copilotMessagesClient.js +0 -78
  84. package/dist/esm/components/bik-copilot/services/copilotMessagesClient.js.map +0 -1
  85. package/dist/esm/components/bik-copilot/services/copilotPageSession.d.ts +0 -37
  86. package/dist/esm/components/bik-copilot/services/copilotPageSession.js +0 -35
  87. package/dist/esm/components/bik-copilot/services/copilotPageSession.js.map +0 -1
  88. package/dist/esm/components/bik-copilot/services/copilotSseParser.d.ts +0 -22
  89. package/dist/esm/components/bik-copilot/services/copilotSseParser.js +0 -52
  90. package/dist/esm/components/bik-copilot/services/copilotSseParser.js.map +0 -1
  91. package/dist/esm/components/bik-copilot/services/copilotStreamClient.d.ts +0 -31
  92. package/dist/esm/components/bik-copilot/services/copilotStreamClient.js +0 -103
  93. package/dist/esm/components/bik-copilot/services/copilotStreamClient.js.map +0 -1
  94. package/dist/esm/components/bik-copilot/useCopilotIcebreakers.d.ts +0 -17
  95. package/dist/esm/components/bik-copilot/useCopilotIcebreakers.js +0 -60
  96. package/dist/esm/components/bik-copilot/useCopilotIcebreakers.js.map +0 -1
  97. package/dist/esm/components/bik-copilot/useCopilotStreamChat.d.ts +0 -20
  98. package/dist/esm/components/bik-copilot/useCopilotStreamChat.js +0 -333
  99. package/dist/esm/components/bik-copilot/useCopilotStreamChat.js.map +0 -1
  100. package/dist/esm/components/bik-copilot/useDraggableFloater.d.ts +0 -9
  101. package/dist/esm/components/bik-copilot/useDraggableFloater.js +0 -118
  102. package/dist/esm/components/bik-copilot/useDraggableFloater.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bikdotai/bik-component-library",
3
- "version": "0.0.863-beta.1",
3
+ "version": "0.0.863-beta.3",
4
4
  "description": "Bik Component Library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const V=require("react/jsx-runtime"),e=require("react"),W=require("./ControlledCopilot.js"),X=require("./useCopilotIcebreakers.js"),Y=require("./useCopilotStreamChat.js"),Z=({baseUrl:s,endpointPath:b,icebreakersPath:M,headers:o,authToken:t,getAuthToken:r,fetchImpl:i,storeId:n,agent:a,route:l,email:m,systemPrompt:h,model:q,maxOutputTokens:k,sessionId:y,persist:O,loadIcebreakers:R=!0,onError:j,onResponseComplete:H,onSessionIdChange:v,suggestions:B,inputDisabled:I,onRefresh:u,open:c,defaultOpen:C,onOpenChange:d,...K})=>{const[L,f]=e.useState(C===!0||c===!0),{messages:w,isThinking:x,isStreaming:g,isRestoring:D,error:N,isLoadingHistory:P,hasMoreHistory:z,sendMessage:E,loadOlderMessages:F,stopStreaming:G,startNewConversation:p}=Y.useCopilotStreamChat({baseUrl:s,endpointPath:b,headers:o,authToken:t,getAuthToken:r,fetchImpl:i,storeId:n,agent:a,route:l,email:m,systemPrompt:h,model:q,maxOutputTokens:k,sessionId:y,persist:O,onError:j,onResponseComplete:H,onSessionIdChange:v}),{icebreakers:J}=X.useCopilotIcebreakers({baseUrl:s,icebreakersPath:M,headers:o,authToken:t,getAuthToken:r,fetchImpl:i,agent:a,route:l,storeId:n,enabled:R&&L}),Q=e.useCallback(S=>{S&&f(!0),d?.(S)},[d]),T=e.useCallback(()=>{p(),u?.()},[u,p]);return V.jsx(W.ControlledCopilot,{...K,open:c,defaultOpen:C,onOpenChange:Q,messages:w,onSendMessage:E,isThinking:x,isStreaming:g,onStop:G,isLoadingHistory:P,hasMoreHistory:z,onLoadOlderMessages:F,errorMessage:N,suggestions:B??J,inputDisabled:I||D||g,onRefresh:T})};exports.BIKCopilot=Z;
2
- //# sourceMappingURL=BIKCopilot.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BIKCopilot.js","sources":["../../../../src/components/bik-copilot/BIKCopilot.tsx"],"sourcesContent":["import React, { useCallback, useState } from 'react';\nimport { ControlledCopilot } from './ControlledCopilot';\nimport { BIKCopilotProps } from './model';\nimport { useCopilotIcebreakers } from './useCopilotIcebreakers';\nimport { useCopilotStreamChat } from './useCopilotStreamChat';\n\n/**\n * The copilot ball and panel wired to the streaming `/bik-ai/copilot-chatbot`\n * endpoint, with the transcript persisted in IndexedDB and route-aware ice\n * breakers from `/bik-ai/copilot-icebreakers`.\n *\n * Chunks arrive as `STREAM` events and are appended live; the final `TEXT` event\n * replaces the bubble with the authoritative full message and carries the\n * `responseId` that threads the next turn. A session id is created on first use\n * and restored on reload, so a refresh resumes the same conversation. The\n * header's reset button starts a new session id and a new OpenAI thread.\n *\n * Ice breakers are fetched for the current `agent` + `route` the first time the\n * panel is opened, and refetched when the route changes.\n *\n * ```tsx\n * <BIKCopilot\n * baseUrl={AI_BACKEND_URL}\n * getAuthToken={() => firebaseUser.getIdToken()}\n * headers={{ 'bik-referer': 'dashboard' }}\n * storeId={storeId}\n * email={user.email}\n * route={currentRoute}\n * title=\"Copilot\"\n * badge=\"New\"\n * subtitle=\"Way smarter, wildly more capable\"\n * />\n * ```\n */\nexport const BIKCopilot: React.FC<BIKCopilotProps> = ({\n\t// Transport + turn config\n\tbaseUrl,\n\tendpointPath,\n\ticebreakersPath,\n\theaders,\n\tauthToken,\n\tgetAuthToken,\n\tfetchImpl,\n\tstoreId,\n\tagent,\n\troute,\n\temail,\n\tsystemPrompt,\n\tmodel,\n\tmaxOutputTokens,\n\tsessionId,\n\tpersist,\n\tloadIcebreakers = true,\n\tonError,\n\tonResponseComplete,\n\tonSessionIdChange,\n\t// Shell\n\tsuggestions,\n\tinputDisabled,\n\tonRefresh,\n\topen,\n\tdefaultOpen,\n\tonOpenChange,\n\t...shellProps\n}) => {\n\t// Ice breakers only matter once the panel is visible, so a merchant who never\n\t// opens the copilot costs no request.\n\tconst [hasOpened, setHasOpened] = useState(\n\t\tdefaultOpen === true || open === true,\n\t);\n\n\tconst {\n\t\tmessages,\n\t\tisThinking,\n\t\tisStreaming,\n\t\tisRestoring,\n\t\terror,\n\t\tisLoadingHistory,\n\t\thasMoreHistory,\n\t\tsendMessage,\n\t\tloadOlderMessages,\n\t\tstopStreaming,\n\t\tstartNewConversation,\n\t} = useCopilotStreamChat({\n\t\tbaseUrl,\n\t\tendpointPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tagent,\n\t\troute,\n\t\temail,\n\t\tsystemPrompt,\n\t\tmodel,\n\t\tmaxOutputTokens,\n\t\tsessionId,\n\t\tpersist,\n\t\tonError,\n\t\tonResponseComplete,\n\t\tonSessionIdChange,\n\t});\n\n\tconst { icebreakers } = useCopilotIcebreakers({\n\t\tbaseUrl,\n\t\ticebreakersPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tagent,\n\t\troute,\n\t\tstoreId,\n\t\tenabled: loadIcebreakers && hasOpened,\n\t});\n\n\tconst handleOpenChange = useCallback(\n\t\t(nextOpen: boolean) => {\n\t\t\tif (nextOpen) {\n\t\t\t\tsetHasOpened(true);\n\t\t\t}\n\t\t\tonOpenChange?.(nextOpen);\n\t\t},\n\t\t[onOpenChange],\n\t);\n\n\tconst handleRefresh = useCallback(() => {\n\t\tstartNewConversation();\n\t\tonRefresh?.();\n\t}, [onRefresh, startNewConversation]);\n\n\treturn (\n\t\t<ControlledCopilot\n\t\t\t{...shellProps}\n\t\t\topen={open}\n\t\t\tdefaultOpen={defaultOpen}\n\t\t\tonOpenChange={handleOpenChange}\n\t\t\tmessages={messages}\n\t\t\tonSendMessage={sendMessage}\n\t\t\tisThinking={isThinking}\n\t\t\tisStreaming={isStreaming}\n\t\t\tonStop={stopStreaming}\n\t\t\tisLoadingHistory={isLoadingHistory}\n\t\t\thasMoreHistory={hasMoreHistory}\n\t\t\tonLoadOlderMessages={loadOlderMessages}\n\t\t\terrorMessage={error}\n\t\t\t// An explicit list wins; otherwise the route's fetched prompts show. A\n\t\t\t// failed or empty fetch simply leaves the empty state without chips.\n\t\t\tsuggestions={suggestions ?? icebreakers}\n\t\t\t// A second prompt mid-stream would race the thread's responseId.\n\t\t\tinputDisabled={inputDisabled || isRestoring || isStreaming}\n\t\t\tonRefresh={handleRefresh}\n\t\t/>\n\t);\n};\n\nexport default BIKCopilot;\n"],"names":["BIKCopilot","baseUrl","endpointPath","icebreakersPath","headers","authToken","getAuthToken","fetchImpl","storeId","agent","route","email","systemPrompt","model","maxOutputTokens","sessionId","persist","loadIcebreakers","onError","onResponseComplete","onSessionIdChange","suggestions","inputDisabled","onRefresh","open","defaultOpen","onOpenChange","shellProps","hasOpened","setHasOpened","useState","messages","isThinking","isStreaming","isRestoring","error","isLoadingHistory","hasMoreHistory","sendMessage","loadOlderMessages","stopStreaming","startNewConversation","useCopilotStreamChat","icebreakers","useCopilotIcebreakers","handleOpenChange","useCallback","nextOpen","handleRefresh","jsx","ControlledCopilot"],"mappings":"2PAkCaA,EAAwC,CAAC,CAErD,QAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,QAAAC,EACA,UAAAC,EACA,aAAAC,EACA,UAAAC,EACA,QAAAC,EACA,MAAAC,EACA,MAAAC,EACA,MAAAC,EACA,aAAAC,EACA,MAAAC,EACA,gBAAAC,EACA,UAAAC,EACA,QAAAC,EACA,gBAAAC,EAAkB,GAClB,QAAAC,EACA,mBAAAC,EACA,kBAAAC,EAEA,YAAAC,EACA,cAAAC,EACA,UAAAC,EACA,KAAAC,EACA,YAAAC,EACA,aAAAC,EACA,GAAGC,CACJ,IAAM,CAGL,KAAM,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SACjCL,IAAgB,IAAQD,IAAS,EAAA,EAG5B,CACL,SAAAO,EACA,WAAAC,EACA,YAAAC,EACA,YAAAC,EACA,MAAAC,EACA,iBAAAC,EACA,eAAAC,EACA,YAAAC,EACA,kBAAAC,EACA,cAAAC,EACA,qBAAAC,CAAA,EACGC,uBAAqB,CACxB,QAAAzC,EACA,aAAAC,EACA,QAAAE,EACA,UAAAC,EACA,aAAAC,EACA,UAAAC,EACA,QAAAC,EACA,MAAAC,EACA,MAAAC,EACA,MAAAC,EACA,aAAAC,EACA,MAAAC,EACA,gBAAAC,EACA,UAAAC,EACA,QAAAC,EACA,QAAAE,EACA,mBAAAC,EACA,kBAAAC,CAAA,CACA,EAEK,CAAE,YAAAuB,CAAA,EAAgBC,wBAAsB,CAC7C,QAAA3C,EACA,gBAAAE,EACA,QAAAC,EACA,UAAAC,EACA,aAAAC,EACA,UAAAC,EACA,MAAAE,EACA,MAAAC,EACA,QAAAF,EACA,QAASS,GAAmBW,CAAA,CAC5B,EAEKiB,EAAmBC,EAAAA,YACvBC,GAAsB,CAClBA,GACHlB,EAAa,EAAI,EAElBH,IAAeqB,CAAQ,CACxB,EACA,CAACrB,CAAY,CAAA,EAGRsB,EAAgBF,EAAAA,YAAY,IAAM,CACvCL,EAAA,EACAlB,IAAA,CACD,EAAG,CAACA,EAAWkB,CAAoB,CAAC,EAEpC,OACCQ,EAAAA,IAACC,EAAAA,kBAAA,CACC,GAAGvB,EACJ,KAAAH,EACA,YAAAC,EACA,aAAcoB,EACd,SAAAd,EACA,cAAeO,EACf,WAAAN,EACA,YAAAC,EACA,OAAQO,EACR,iBAAAJ,EACA,eAAAC,EACA,oBAAqBE,EACrB,aAAcJ,EAGd,YAAad,GAAesB,EAE5B,cAAerB,GAAiBY,GAAeD,EAC/C,UAAWe,CAAA,CAAA,CAGd"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),n=require("react"),fe=require("../../constants/Theme.js"),pe=require("./ControlledCopilot.styled.js"),v=require("./CopilotBall.js"),ge=require("./CopilotPanel.js"),Ce=require("./copilotPlacement.js"),me=require("./useDraggableFloater.js"),he=({messages:P,onSendMessage:b,isThinking:w=!1,thinkingLabel:L,isStreaming:q=!1,onStop:E,interruptedLabel:k,followUpsLabel:y,hasMoreHistory:T=!1,isLoadingHistory:j=!1,onLoadOlderMessages:O,historyLoadingLabel:R,errorMessage:$,ballSize:s=56,corner:x="bottom-right",offset:B=24,initialPosition:D,draggable:u=!0,snapToEdge:I=!0,onPositionChange:F,ballIcon:S,ballOpenIcon:_,ballColor:A=fe.COLORS.background.brand,zIndex:d=1200,ballAriaLabel:U,panelWidth:z=400,panelHeight:H=700,panelGap:K=12,title:M="Copilot",badge:G,subtitle:J,avatar:N,placeholder:Q,disclaimer:V,emptyStateTitle:W,emptyStateSubtitle:X,suggestions:Y,onSuggestionClick:Z,showRefresh:ee=!0,onRefresh:te,inputDisabled:oe=!1,open:f,defaultOpen:ne=!1,onOpenChange:p,closeOnClickOutside:g=!1,className:re,style:le})=>{const[se,ie]=n.useState(ne),C=n.useRef(null),i=f!==void 0,e=i?f:se,o=n.useCallback(t=>{i||ie(t),p?.(t)},[i,p]),{position:m,isDragging:ae,viewport:ce,dragHandlers:ue,shouldIgnoreClick:h}=me.useDraggableFloater({size:s,corner:x,offset:B,enabled:u,snapToEdge:I,initialPosition:D,onPositionChange:F}),de=n.useCallback(()=>{h()||o(!e)},[e,o,h]);n.useEffect(()=>{if(!e)return;const t=a=>{a.key==="Escape"&&o(!1)};return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[e,o]),n.useEffect(()=>{if(!e||!g)return;const t=a=>{const c=a.target;c&&(C.current?.contains(c)||c.closest(`[${v.COPILOT_BALL_ATTRIBUTE}]`)||o(!1))};return document.addEventListener("pointerdown",t),()=>document.removeEventListener("pointerdown",t)},[g,e,o]);const l=Ce.getCopilotPanelPlacement({ballPosition:m,ballSize:s,panelWidth:z,panelHeight:H,gap:K,viewport:ce});return r.jsxs(r.Fragment,{children:[e&&r.jsx(pe.PanelPositioner,{ref:C,$left:l.left,$top:l.top,$width:l.width,$height:l.height,$zIndex:d,children:r.jsx(ge.CopilotPanel,{messages:P,onSend:b,onClose:()=>o(!1),title:M,badge:G,subtitle:J,avatar:N,placeholder:Q,disclaimer:V,emptyStateTitle:W,emptyStateSubtitle:X,suggestions:Y,onSuggestionClick:Z,showRefresh:ee,onRefresh:te,isThinking:w,thinkingLabel:L,isStreaming:q,onStop:E,interruptedLabel:k,followUpsLabel:y,hasMoreHistory:T,isLoadingHistory:j,onLoadOlderMessages:O,historyLoadingLabel:R,inputDisabled:oe,errorMessage:$,className:re,style:le})}),r.jsx(v.CopilotBall,{isOpen:e,onToggle:de,position:m,size:s,isDragging:ae,draggable:u,color:A,zIndex:d+1,icon:S,openIcon:_,ariaLabel:U,...ue})]})};exports.ControlledCopilot=he;
2
- //# sourceMappingURL=ControlledCopilot.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ControlledCopilot.js","sources":["../../../../src/components/bik-copilot/ControlledCopilot.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { COLORS } from '@src/constants/Theme';\nimport { PanelPositioner } from './ControlledCopilot.styled';\nimport { COPILOT_BALL_ATTRIBUTE, CopilotBall } from './CopilotBall';\nimport { CopilotPanel } from './CopilotPanel';\nimport { getCopilotPanelPlacement } from './copilotPlacement';\nimport { ControlledCopilotProps } from './model';\nimport { useDraggableFloater } from './useDraggableFloater';\n\n/**\n * The presentational half of the copilot: a draggable floating ball that opens a\n * chat panel beside it.\n *\n * Fully controlled — it renders the `messages` it is handed and reports every\n * user action through callbacks, so it carries no backend knowledge. **Use\n * `BIKCopilot` instead** unless you are wiring a backend other than\n * `/bik-ai/copilot-chatbot`; `BIKCopilot` is this component plus the streaming\n * transport, IndexedDB history and route-aware ice breakers.\n */\nexport const ControlledCopilot: React.FC<ControlledCopilotProps> = ({\n\t// Conversation\n\tmessages,\n\tonSendMessage,\n\tisThinking = false,\n\tthinkingLabel,\n\tisStreaming = false,\n\tonStop,\n\tinterruptedLabel,\n\tfollowUpsLabel,\n\thasMoreHistory = false,\n\tisLoadingHistory = false,\n\tonLoadOlderMessages,\n\thistoryLoadingLabel,\n\terrorMessage,\n\t// Ball\n\tballSize = 56,\n\tcorner = 'bottom-right',\n\toffset = 24,\n\tinitialPosition,\n\tdraggable = true,\n\tsnapToEdge = true,\n\tonPositionChange,\n\tballIcon,\n\tballOpenIcon,\n\tballColor = COLORS.background.brand,\n\tzIndex = 1200,\n\tballAriaLabel,\n\t// Panel\n\tpanelWidth = 400,\n\tpanelHeight = 700,\n\tpanelGap = 12,\n\ttitle = 'Copilot',\n\tbadge,\n\tsubtitle,\n\tavatar,\n\tplaceholder,\n\tdisclaimer,\n\temptyStateTitle,\n\temptyStateSubtitle,\n\tsuggestions,\n\tonSuggestionClick,\n\tshowRefresh = true,\n\tonRefresh,\n\tinputDisabled = false,\n\t// Open state\n\topen,\n\tdefaultOpen = false,\n\tonOpenChange,\n\tcloseOnClickOutside = false,\n\tclassName,\n\tstyle,\n}) => {\n\tconst [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n\tconst panelRef = useRef<HTMLDivElement>(null);\n\n\tconst isControlled = open !== undefined;\n\tconst isOpen = isControlled ? open : uncontrolledOpen;\n\n\tconst setOpen = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!isControlled) {\n\t\t\t\tsetUncontrolledOpen(next);\n\t\t\t}\n\t\t\tonOpenChange?.(next);\n\t\t},\n\t\t[isControlled, onOpenChange],\n\t);\n\n\tconst { position, isDragging, viewport, dragHandlers, shouldIgnoreClick } =\n\t\tuseDraggableFloater({\n\t\t\tsize: ballSize,\n\t\t\tcorner,\n\t\t\toffset,\n\t\t\tenabled: draggable,\n\t\t\tsnapToEdge,\n\t\t\tinitialPosition,\n\t\t\tonPositionChange,\n\t\t});\n\n\tconst handleBallClick = useCallback(() => {\n\t\t// The click that ends a drag gesture must not toggle the panel.\n\t\tif (shouldIgnoreClick()) {\n\t\t\treturn;\n\t\t}\n\t\tsetOpen(!isOpen);\n\t}, [isOpen, setOpen, shouldIgnoreClick]);\n\n\t// Escape closes the panel.\n\tuseEffect(() => {\n\t\tif (!isOpen) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst handleKeyDown = (event: KeyboardEvent) => {\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', handleKeyDown);\n\t\treturn () => document.removeEventListener('keydown', handleKeyDown);\n\t}, [isOpen, setOpen]);\n\n\tuseEffect(() => {\n\t\tif (!isOpen || !closeOnClickOutside) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst handlePointerDown = (event: PointerEvent) => {\n\t\t\tconst target = event.target as HTMLElement | null;\n\t\t\tif (!target) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (panelRef.current?.contains(target)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (target.closest(`[${COPILOT_BALL_ATTRIBUTE}]`)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetOpen(false);\n\t\t};\n\t\tdocument.addEventListener('pointerdown', handlePointerDown);\n\t\treturn () => document.removeEventListener('pointerdown', handlePointerDown);\n\t}, [closeOnClickOutside, isOpen, setOpen]);\n\n\tconst placement = getCopilotPanelPlacement({\n\t\tballPosition: position,\n\t\tballSize,\n\t\tpanelWidth,\n\t\tpanelHeight,\n\t\tgap: panelGap,\n\t\tviewport,\n\t});\n\n\treturn (\n\t\t<>\n\t\t\t{isOpen && (\n\t\t\t\t<PanelPositioner\n\t\t\t\t\tref={panelRef}\n\t\t\t\t\t$left={placement.left}\n\t\t\t\t\t$top={placement.top}\n\t\t\t\t\t$width={placement.width}\n\t\t\t\t\t$height={placement.height}\n\t\t\t\t\t$zIndex={zIndex}\n\t\t\t\t>\n\t\t\t\t\t<CopilotPanel\n\t\t\t\t\t\tmessages={messages}\n\t\t\t\t\t\tonSend={onSendMessage}\n\t\t\t\t\t\tonClose={() => setOpen(false)}\n\t\t\t\t\t\ttitle={title}\n\t\t\t\t\t\tbadge={badge}\n\t\t\t\t\t\tsubtitle={subtitle}\n\t\t\t\t\t\tavatar={avatar}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\tdisclaimer={disclaimer}\n\t\t\t\t\t\temptyStateTitle={emptyStateTitle}\n\t\t\t\t\t\temptyStateSubtitle={emptyStateSubtitle}\n\t\t\t\t\t\tsuggestions={suggestions}\n\t\t\t\t\t\tonSuggestionClick={onSuggestionClick}\n\t\t\t\t\t\tshowRefresh={showRefresh}\n\t\t\t\t\t\tonRefresh={onRefresh}\n\t\t\t\t\t\tisThinking={isThinking}\n\t\t\t\t\t\tthinkingLabel={thinkingLabel}\n\t\t\t\t\t\tisStreaming={isStreaming}\n\t\t\t\t\t\tonStop={onStop}\n\t\t\t\t\t\tinterruptedLabel={interruptedLabel}\n\t\t\t\t\t\tfollowUpsLabel={followUpsLabel}\n\t\t\t\t\t\thasMoreHistory={hasMoreHistory}\n\t\t\t\t\t\tisLoadingHistory={isLoadingHistory}\n\t\t\t\t\t\tonLoadOlderMessages={onLoadOlderMessages}\n\t\t\t\t\t\thistoryLoadingLabel={historyLoadingLabel}\n\t\t\t\t\t\tinputDisabled={inputDisabled}\n\t\t\t\t\t\terrorMessage={errorMessage}\n\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\tstyle={style}\n\t\t\t\t\t/>\n\t\t\t\t</PanelPositioner>\n\t\t\t)}\n\n\t\t\t<CopilotBall\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tonToggle={handleBallClick}\n\t\t\t\tposition={position}\n\t\t\t\tsize={ballSize}\n\t\t\t\tisDragging={isDragging}\n\t\t\t\tdraggable={draggable}\n\t\t\t\tcolor={ballColor}\n\t\t\t\tzIndex={zIndex + 1}\n\t\t\t\ticon={ballIcon}\n\t\t\t\topenIcon={ballOpenIcon}\n\t\t\t\tariaLabel={ballAriaLabel}\n\t\t\t\t{...dragHandlers}\n\t\t\t/>\n\t\t</>\n\t);\n};\n\nexport default ControlledCopilot;\n"],"names":["ControlledCopilot","messages","onSendMessage","isThinking","thinkingLabel","isStreaming","onStop","interruptedLabel","followUpsLabel","hasMoreHistory","isLoadingHistory","onLoadOlderMessages","historyLoadingLabel","errorMessage","ballSize","corner","offset","initialPosition","draggable","snapToEdge","onPositionChange","ballIcon","ballOpenIcon","ballColor","COLORS","zIndex","ballAriaLabel","panelWidth","panelHeight","panelGap","title","badge","subtitle","avatar","placeholder","disclaimer","emptyStateTitle","emptyStateSubtitle","suggestions","onSuggestionClick","showRefresh","onRefresh","inputDisabled","open","defaultOpen","onOpenChange","closeOnClickOutside","className","style","uncontrolledOpen","setUncontrolledOpen","useState","panelRef","useRef","isControlled","isOpen","setOpen","useCallback","next","position","isDragging","viewport","dragHandlers","shouldIgnoreClick","useDraggableFloater","handleBallClick","useEffect","handleKeyDown","event","handlePointerDown","target","COPILOT_BALL_ATTRIBUTE","placement","getCopilotPanelPlacement","jsxs","Fragment","jsx","PanelPositioner","CopilotPanel","CopilotBall"],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("styled-components"),o=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},i=o(e),a=i.default.div`
2
- position: fixed;
3
- left: ${t=>t.$left}px;
4
- top: ${t=>t.$top}px;
5
- width: ${t=>t.$width}px;
6
- height: ${t=>t.$height}px;
7
- z-index: ${t=>t.$zIndex};
8
- display: flex;
9
- animation: bikCopilotPanelIn 0.16s ease-out;
10
-
11
- > * {
12
- flex: 1;
13
- min-width: 0;
14
- }
15
-
16
- @keyframes bikCopilotPanelIn {
17
- from {
18
- opacity: 0;
19
- transform: translateY(6px) scale(0.98);
20
- }
21
- to {
22
- opacity: 1;
23
- transform: translateY(0) scale(1);
24
- }
25
- }
26
- `;exports.PanelPositioner=a;
27
- //# sourceMappingURL=ControlledCopilot.styled.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ControlledCopilot.styled.js","sources":["../../../../src/components/bik-copilot/ControlledCopilot.styled.ts"],"sourcesContent":["import styled from 'styled-components';\n\nexport const PanelPositioner = styled.div<{\n\t$left: number;\n\t$top: number;\n\t$width: number;\n\t$height: number;\n\t$zIndex: number;\n}>`\n\tposition: fixed;\n\tleft: ${(props) => props.$left}px;\n\ttop: ${(props) => props.$top}px;\n\twidth: ${(props) => props.$width}px;\n\theight: ${(props) => props.$height}px;\n\tz-index: ${(props) => props.$zIndex};\n\tdisplay: flex;\n\tanimation: bikCopilotPanelIn 0.16s ease-out;\n\n\t> * {\n\t\tflex: 1;\n\t\tmin-width: 0;\n\t}\n\n\t@keyframes bikCopilotPanelIn {\n\t\tfrom {\n\t\t\topacity: 0;\n\t\t\ttransform: translateY(6px) scale(0.98);\n\t\t}\n\t\tto {\n\t\t\topacity: 1;\n\t\t\ttransform: translateY(0) scale(1);\n\t\t}\n\t}\n`;\n"],"names":["PanelPositioner","styled","props"],"mappings":"oLAEaA,EAAkBC,EAAAA,QAAO;AAAA;AAAA,SAQ5BC,GAAUA,EAAM,KAAK;AAAA,QACtBA,GAAUA,EAAM,IAAI;AAAA,UAClBA,GAAUA,EAAM,MAAM;AAAA,WACrBA,GAAUA,EAAM,OAAO;AAAA,YACtBA,GAAUA,EAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),I=require("../../assets/icons/bik_ai_stars_icon.svg.js"),$=require("../../assets/icons/chevronDown.svg.js"),p=require("./CopilotBall.styled.js"),n="data-bik-copilot-ball",L=({isOpen:o,onToggle:r,position:l,size:i,isDragging:c,draggable:s,color:u,zIndex:d,icon:g,openIcon:h,ariaLabel:B,onPointerDown:T,onPointerMove:b,onPointerUp:_,onPointerCancel:x})=>{const t=Math.round(i*.42),a=o?e.jsx($.default,{width:t,height:t}):e.jsx(I.default,{width:t,height:t}),C=o?h??a:g??a;return e.jsx(p.BallButton,{type:"button",[n]:"true",$size:i,$left:l.x,$top:l.y,$color:u,$zIndex:d,$isDragging:c,$draggable:s,"aria-label":B||"Copilot","aria-expanded":o,onClick:r,onPointerDown:T,onPointerMove:b,onPointerUp:_,onPointerCancel:x,children:C})};exports.COPILOT_BALL_ATTRIBUTE=n;exports.CopilotBall=L;
2
- //# sourceMappingURL=CopilotBall.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopilotBall.js","sources":["../../../../src/components/bik-copilot/CopilotBall.tsx"],"sourcesContent":["import AiStarsIcon from '@src/assets/icons/bik_ai_stars_icon.svg';\nimport ChevronDownIcon from '@src/assets/icons/chevronDown.svg';\nimport React from 'react';\nimport { BallButton } from './CopilotBall.styled';\nimport { CopilotBallProps } from './model';\n\n/**\n * Marks the ball in the DOM so an outside-click handler can tell the ball apart\n * from the rest of the page and not fight the ball's own toggle.\n */\nexport const COPILOT_BALL_ATTRIBUTE = 'data-bik-copilot-ball';\n\n/**\n * The floating ball that opens the copilot panel. Purely presentational — the\n * drag gesture lives in `useDraggableFloater` and is passed in as handlers.\n */\nexport const CopilotBall: React.FC<CopilotBallProps> = ({\n\tisOpen,\n\tonToggle,\n\tposition,\n\tsize,\n\tisDragging,\n\tdraggable,\n\tcolor,\n\tzIndex,\n\ticon,\n\topenIcon,\n\tariaLabel,\n\tonPointerDown,\n\tonPointerMove,\n\tonPointerUp,\n\tonPointerCancel,\n}) => {\n\tconst iconSize = Math.round(size * 0.42);\n\tconst defaultIcon = isOpen ? (\n\t\t<ChevronDownIcon width={iconSize} height={iconSize} />\n\t) : (\n\t\t<AiStarsIcon width={iconSize} height={iconSize} />\n\t);\n\tconst activeIcon = isOpen ? openIcon ?? defaultIcon : icon ?? defaultIcon;\n\n\treturn (\n\t\t<BallButton\n\t\t\ttype=\"button\"\n\t\t\t{...{ [COPILOT_BALL_ATTRIBUTE]: 'true' }}\n\t\t\t$size={size}\n\t\t\t$left={position.x}\n\t\t\t$top={position.y}\n\t\t\t$color={color}\n\t\t\t$zIndex={zIndex}\n\t\t\t$isDragging={isDragging}\n\t\t\t$draggable={draggable}\n\t\t\t/* A disclosure button keeps a stable name and reports its state through\n\t\t\t aria-expanded, so this must not become \"Open/Close copilot\" — that\n\t\t\t would also collide with the panel's own close button. */\n\t\t\taria-label={ariaLabel || 'Copilot'}\n\t\t\taria-expanded={isOpen}\n\t\t\tonClick={onToggle}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonPointerMove={onPointerMove}\n\t\t\tonPointerUp={onPointerUp}\n\t\t\tonPointerCancel={onPointerCancel}\n\t\t>\n\t\t\t{activeIcon}\n\t\t</BallButton>\n\t);\n};\n\nexport default CopilotBall;\n"],"names":["COPILOT_BALL_ATTRIBUTE","CopilotBall","isOpen","onToggle","position","size","isDragging","draggable","color","zIndex","icon","openIcon","ariaLabel","onPointerDown","onPointerMove","onPointerUp","onPointerCancel","iconSize","defaultIcon","jsx","ChevronDownIcon","AiStarsIcon","activeIcon","BallButton"],"mappings":"sQAUaA,EAAyB,wBAMzBC,EAA0C,CAAC,CACvD,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,KAAAC,EACA,WAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,KAAAC,EACA,SAAAC,EACA,UAAAC,EACA,cAAAC,EACA,cAAAC,EACA,YAAAC,EACA,gBAAAC,CACD,IAAM,CACL,MAAMC,EAAW,KAAK,MAAMZ,EAAO,GAAI,EACjCa,EAAchB,EACnBiB,EAAAA,IAACC,EAAAA,QAAA,CAAgB,MAAOH,EAAU,OAAQA,CAAA,CAAU,EAEpDE,EAAAA,IAACE,UAAA,CAAY,MAAOJ,EAAU,OAAQA,EAAU,EAE3CK,EAAapB,EAASS,GAAYO,EAAcR,GAAQQ,EAE9D,OACCC,EAAAA,IAACI,EAAAA,WAAA,CACA,KAAK,SACC,CAACvB,CAAsB,EAAG,OAChC,MAAOK,EACP,MAAOD,EAAS,EAChB,KAAMA,EAAS,EACf,OAAQI,EACR,QAASC,EACT,YAAaH,EACb,WAAYC,EAIZ,aAAYK,GAAa,UACzB,gBAAeV,EACf,QAASC,EACT,cAAAU,EACA,cAAAC,EACA,YAAAC,EACA,gBAAAC,EAEC,SAAAM,CAAA,CAAA,CAGJ"}
@@ -1,42 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("styled-components"),o=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},s=o(t),n=s.default.button`
2
- position: fixed;
3
- left: ${e=>e.$left}px;
4
- top: ${e=>e.$top}px;
5
- width: ${e=>e.$size}px;
6
- height: ${e=>e.$size}px;
7
- z-index: ${e=>e.$zIndex};
8
-
9
- display: flex;
10
- align-items: center;
11
- justify-content: center;
12
- padding: 0;
13
- border: none;
14
- border-radius: 50%;
15
- background: ${e=>e.$color};
16
- color: #ffffff;
17
- box-shadow: ${e=>e.$isDragging?"0 12px 32px rgba(40, 3, 78, 0.36)":"0 6px 20px rgba(40, 3, 78, 0.24)"};
18
-
19
- cursor: ${e=>e.$isDragging?"grabbing":e.$draggable?"grab":"pointer"};
20
- touch-action: none;
21
- user-select: none;
22
- -webkit-user-select: none;
23
-
24
- /* Position changes animate on release but must track the pointer 1:1 while
25
- the user is dragging. */
26
- transition: ${e=>e.$isDragging?"box-shadow 0.15s ease, transform 0.15s ease":"left 0.22s ease, top 0.22s ease, box-shadow 0.15s ease, transform 0.15s ease"};
27
- transform: ${e=>e.$isDragging?"scale(1.06)":"scale(1)"};
28
-
29
- &:hover {
30
- transform: scale(1.06);
31
- }
32
-
33
- &:focus-visible {
34
- outline: 2px solid #ffffff;
35
- outline-offset: 2px;
36
- }
37
-
38
- svg {
39
- pointer-events: none;
40
- }
41
- `;exports.BallButton=n;
42
- //# sourceMappingURL=CopilotBall.styled.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopilotBall.styled.js","sources":["../../../../src/components/bik-copilot/CopilotBall.styled.ts"],"sourcesContent":["import styled from 'styled-components';\n\nexport const BallButton = styled.button<{\n\t$size: number;\n\t$left: number;\n\t$top: number;\n\t$color: string;\n\t$zIndex: number;\n\t$isDragging: boolean;\n\t$draggable: boolean;\n}>`\n\tposition: fixed;\n\tleft: ${(props) => props.$left}px;\n\ttop: ${(props) => props.$top}px;\n\twidth: ${(props) => props.$size}px;\n\theight: ${(props) => props.$size}px;\n\tz-index: ${(props) => props.$zIndex};\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 0;\n\tborder: none;\n\tborder-radius: 50%;\n\tbackground: ${(props) => props.$color};\n\tcolor: #ffffff;\n\tbox-shadow: ${(props) =>\n\t\tprops.$isDragging\n\t\t\t? '0 12px 32px rgba(40, 3, 78, 0.36)'\n\t\t\t: '0 6px 20px rgba(40, 3, 78, 0.24)'};\n\n\tcursor: ${(props) =>\n\t\tprops.$isDragging ? 'grabbing' : props.$draggable ? 'grab' : 'pointer'};\n\ttouch-action: none;\n\tuser-select: none;\n\t-webkit-user-select: none;\n\n\t/* Position changes animate on release but must track the pointer 1:1 while\n\t the user is dragging. */\n\ttransition: ${(props) =>\n\t\tprops.$isDragging\n\t\t\t? 'box-shadow 0.15s ease, transform 0.15s ease'\n\t\t\t: 'left 0.22s ease, top 0.22s ease, box-shadow 0.15s ease, transform 0.15s ease'};\n\ttransform: ${(props) => (props.$isDragging ? 'scale(1.06)' : 'scale(1)')};\n\n\t&:hover {\n\t\ttransform: scale(1.06);\n\t}\n\n\t&:focus-visible {\n\t\toutline: 2px solid #ffffff;\n\t\toutline-offset: 2px;\n\t}\n\n\tsvg {\n\t\tpointer-events: none;\n\t}\n`;\n"],"names":["BallButton","styled","props"],"mappings":"oLAEaA,EAAaC,EAAAA,QAAO;AAAA;AAAA,SAUvBC,GAAUA,EAAM,KAAK;AAAA,QACtBA,GAAUA,EAAM,IAAI;AAAA,UAClBA,GAAUA,EAAM,KAAK;AAAA,WACpBA,GAAUA,EAAM,KAAK;AAAA,YACpBA,GAAUA,EAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAQpBA,GAAUA,EAAM,MAAM;AAAA;AAAA,eAEtBA,GACdA,EAAM,YACH,oCACA,kCAAkC;AAAA;AAAA,WAE3BA,GACVA,EAAM,YAAc,WAAaA,EAAM,WAAa,OAAS,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAOxDA,GACdA,EAAM,YACH,8CACA,8EAA8E;AAAA,cACpEA,GAAWA,EAAM,YAAc,cAAgB,UAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),f=require("../../assets/icons/bik_ai_stars_icon.svg.js"),ye=require("../../assets/icons/cross.svg.js"),Ce=require("../../assets/icons/refresh.svg.js"),n=require("react"),h=require("../../constants/Theme.js"),ge=require("../bik-chatbot/utils/markdown.js"),w=require("../TypographyStyle.js"),o=require("./CopilotPanel.styled.js"),J=require("../dot-pulse/DotPulse.js"),ke=r=>r&&typeof r=="object"&&"default"in r?r:{default:r},ve=ke(n),Te=96,be=24,Se=1800,Ie=async r=>{try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(r),!0}catch{}try{const s=document.createElement("textarea");s.value=r,s.setAttribute("readonly",""),s.style.position="fixed",s.style.top="-1000px",s.style.opacity="0",document.body.appendChild(s),s.select();const y=document.execCommand("copy");return document.body.removeChild(s),y}catch{return!1}},me=48,Re=()=>e.jsxs("svg",{viewBox:"0 0 24 24",width:"16",height:"16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[e.jsx("path",{d:"M12 19V5"}),e.jsx("path",{d:"M6 11l6-6 6 6"})]}),Ae=()=>e.jsxs("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[e.jsx("path",{d:"M5 12h14"}),e.jsx("path",{d:"M13 6l6 6-6 6"})]}),G=({size:r=16})=>e.jsx("svg",{viewBox:"0 0 24 24",width:r,height:r,fill:"currentColor","aria-hidden":"true",children:e.jsx("rect",{x:"7",y:"7",width:"10",height:"10",rx:"2"})}),Le=()=>e.jsxs("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[e.jsx("rect",{x:"9",y:"9",width:"11",height:"11",rx:"2"}),e.jsx("path",{d:"M15 5.5A1.5 1.5 0 0 0 13.5 4H5.5A1.5 1.5 0 0 0 4 5.5v8A1.5 1.5 0 0 0 5.5 15"})]}),Me=()=>e.jsx("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:e.jsx("path",{d:"M5 13l4 4L19 7"})}),Be=()=>e.jsx("svg",{viewBox:"0 0 24 24",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:e.jsx("path",{d:"M6 9l6 6 6-6"})}),_e=({messages:r,onSend:s,onClose:y,title:C="Copilot",badge:L,subtitle:M,avatar:Q,placeholder:Y="Write your message...",disclaimer:B="AI can make mistakes, Verify the responses.",emptyStateTitle:Z,emptyStateSubtitle:_="Here are some things you can try",suggestions:g,onSuggestionClick:ee,showRefresh:te=!0,onRefresh:E,isThinking:u=!1,thinkingLabel:O="Thinking",isStreaming:oe=!1,onStop:F,interruptedLabel:P="This message was interrupted",followUpsLabel:H="Follow ups",hasMoreHistory:re=!1,isLoadingHistory:p=!1,onLoadOlderMessages:q,historyLoadingLabel:ne="Loading earlier messages",inputDisabled:i=!1,errorMessage:W,width:se,height:le,className:ie,style:ce})=>{const[k,$]=n.useState(""),[ae,D]=n.useState(!1),[v,T]=n.useState(!0),[x,N]=n.useState(null),U=n.useRef(null),a=n.useRef(null),b=n.useRef(null),S=n.useRef(null),I=n.useRef(0),m=n.useRef(null),j=r.filter(t=>t.content.length>0||t.wasInterrupted),V=j.length===0&&!u,c=u||oe,K=!i&&!c&&k.trim().length>0,d=c&&!!F,X=j[j.length-1],R=!c&&X?.role==="assistant"?X.followUps:void 0,A=!V&&!v;n.useEffect(()=>{v&&b.current?.scrollIntoView({behavior:"smooth"})},[r,u,v]),n.useEffect(()=>{const t=S.current,l=m.current;!t||l===null||p||(m.current=null,t.scrollTop=t.scrollHeight-l,I.current=t.scrollTop)},[r,p]);const de=()=>{const t=S.current;if(!t)return;const l=t.scrollHeight-t.scrollTop-t.clientHeight;t.scrollTop<=me&&re&&!p&&q&&(m.current=t.scrollHeight-t.scrollTop,q());const we=t.scrollTop<I.current-1;if(I.current=t.scrollTop,l<=be){T(!0);return}we&&T(!1)},he=()=>{T(!0),b.current?.scrollIntoView({behavior:"smooth"})};n.useEffect(()=>()=>{a.current&&window.clearTimeout(a.current)},[]);const ue=async t=>{await Ie(t.content)&&(a.current&&window.clearTimeout(a.current),N(t.id),a.current=window.setTimeout(()=>N(null),Se))},z=()=>{const t=k.trim();if(!t||i||c)return;s(t),$("");const l=U.current;l&&(l.style.height="auto")},pe=t=>{$(t.target.value);const l=t.target;l.style.height="auto",l.style.height=`${Math.min(l.scrollHeight,Te)}px`},xe=t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),z())},je=t=>{i||c||(ee?.(t),s(t.text))},fe=t=>{i||c||s(t)};return e.jsxs(o.PanelContainer,{className:ie,style:{width:se,height:le,...ce},role:"dialog","aria-label":C,children:[e.jsxs(o.PanelHeader,{children:[e.jsx(o.HeaderAvatar,{children:Q??e.jsx(f.default,{width:18,height:18})}),e.jsxs(o.HeaderText,{children:[e.jsxs(o.HeaderTitleRow,{children:[e.jsx(w.TitleSmall,{children:C}),L&&e.jsx(o.HeaderBadge,{children:L})]}),M&&e.jsx(w.BodyCaption,{color:h.COLORS.content.secondary,children:M})]}),e.jsxs(o.HeaderActions,{children:[te&&E&&e.jsx(o.IconAction,{type:"button",onClick:E,"aria-label":"Start a new conversation",children:e.jsx(Ce.default,{width:16,height:16})}),e.jsx(o.IconAction,{type:"button",onClick:y,"aria-label":"Close copilot",children:e.jsx(ye.default,{width:18,height:18})})]})]}),e.jsxs(o.MessagesViewport,{children:[e.jsx(o.MessagesArea,{ref:S,onScroll:de,role:"region","aria-label":"Conversation",children:V?e.jsxs(o.EmptyState,{children:[e.jsx(o.EmptyStateIcon,{children:e.jsx(f.default,{width:28,height:28})}),e.jsx(w.BodySecondary,{style:{fontWeight:600},children:Z||C}),_&&e.jsx(w.BodyCaption,{color:h.COLORS.content.secondary,children:_}),g&&g.length>0&&e.jsx(o.SuggestionList,{children:g.map(t=>e.jsxs(o.SuggestionChip,{type:"button",disabled:i||c,onClick:()=>je(t),children:[e.jsx(f.default,{width:14,height:14}),t.text]},t.id))})]}):e.jsxs(e.Fragment,{children:[p&&e.jsxs(o.HistoryLoader,{role:"status","aria-live":"polite",children:[e.jsx(J.DotPulse,{color:h.COLORS.content.placeholder,size:4}),ne]}),j.map(t=>e.jsxs(ve.default.Fragment,{children:[t.content.length>0&&e.jsx(o.MessageBubble,{$role:t.role,children:t.role==="assistant"?e.jsx("div",{dangerouslySetInnerHTML:{__html:ge.renderMarkdownLite(t.content)}}):e.jsx("div",{style:{whiteSpace:"pre-wrap"},children:t.content})}),t.wasInterrupted&&P&&e.jsxs(o.InterruptedNote,{children:[e.jsx(G,{size:12}),P]}),t.role==="assistant"&&t.content.length>0&&!t.isStreaming&&e.jsx(o.MessageActions,{children:e.jsx(o.MessageAction,{type:"button",onClick:()=>{ue(t)},"data-copied":x===t.id,title:x===t.id?"Copied":"Copy","aria-label":x===t.id?"Response copied to clipboard":"Copy response",children:x===t.id?e.jsx(Me,{}):e.jsx(Le,{})})})]},t.id)),R&&R.length>0&&e.jsxs(o.FollowUpList,{children:[H&&e.jsx(o.FollowUpsLabel,{children:H}),R.map(t=>e.jsxs(o.FollowUpChip,{type:"button",disabled:i,onClick:()=>fe(t),children:[e.jsx(Ae,{}),t]},t))]}),u&&e.jsxs(o.ThinkingBubble,{role:"status","aria-live":"polite",children:[e.jsx(f.default,{width:14,height:14,color:h.COLORS.content.brand}),O&&e.jsx(o.ThinkingLabel,{children:O}),e.jsx(J.DotPulse,{color:h.COLORS.background.brand,size:5})]}),e.jsx("div",{ref:b})]})}),e.jsx(o.ScrollFade,{$visible:A,"aria-hidden":"true"}),e.jsx(o.JumpToLatestButton,{type:"button",$visible:A,onClick:he,tabIndex:A?0:-1,"aria-label":"Scroll to the latest message",children:e.jsx(Be,{})})]}),W&&e.jsx(o.ErrorBanner,{role:"alert",children:W}),e.jsx(o.InputArea,{children:e.jsxs(o.InputWrapper,{$focused:ae,children:[e.jsx(o.MessageInput,{ref:U,rows:1,value:k,placeholder:Y,disabled:i,onChange:pe,onKeyDown:xe,onFocus:()=>D(!0),onBlur:()=>D(!1)}),e.jsx(o.SendButton,{type:"button",$active:d||K,disabled:!d&&!K,onClick:d?F:z,"aria-label":d?"Stop generating":"Send message",children:d?e.jsx(G,{}):e.jsx(Re,{})})]})}),B&&e.jsx(o.Disclaimer,{children:B})]})};exports.CopilotPanel=_e;
2
- //# sourceMappingURL=CopilotPanel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopilotPanel.js","sources":["../../../../src/components/bik-copilot/CopilotPanel.tsx"],"sourcesContent":["import AiStarsIcon from '@src/assets/icons/bik_ai_stars_icon.svg';\nimport CrossIcon from '@src/assets/icons/cross.svg';\nimport RefreshIcon from '@src/assets/icons/refresh.svg';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { COLORS } from '@src/constants/Theme';\nimport { renderMarkdownLite } from '../bik-chatbot/utils/markdown';\nimport { DotPulse } from '../dot-pulse';\nimport { BodyCaption, BodySecondary, TitleSmall } from '../TypographyStyle';\nimport {\n\tDisclaimer,\n\tEmptyState,\n\tEmptyStateIcon,\n\tErrorBanner,\n\tFollowUpChip,\n\tFollowUpList,\n\tFollowUpsLabel,\n\tHeaderActions,\n\tHeaderAvatar,\n\tHeaderBadge,\n\tHeaderText,\n\tHeaderTitleRow,\n\tHistoryLoader,\n\tIconAction,\n\tInputArea,\n\tInputWrapper,\n\tInterruptedNote,\n\tJumpToLatestButton,\n\tMessageAction,\n\tMessageActions,\n\tMessageBubble,\n\tMessageInput,\n\tMessagesArea,\n\tMessagesViewport,\n\tPanelContainer,\n\tPanelHeader,\n\tScrollFade,\n\tSendButton,\n\tSuggestionChip,\n\tSuggestionList,\n\tThinkingBubble,\n\tThinkingLabel,\n} from './CopilotPanel.styled';\nimport { CopilotPanelProps } from './model';\n\nconst MAX_INPUT_HEIGHT_PX = 96;\n\n/** Slack at the bottom of the scroller that still counts as \"at the latest\". */\nconst AT_BOTTOM_TOLERANCE_PX = 24;\n\n/** How long the copy button shows its confirmation before reverting. */\nconst COPIED_FEEDBACK_MS = 1800;\n\n/**\n * Writes text to the clipboard.\n *\n * `navigator.clipboard` is missing outside a secure context and can reject when\n * the document is not focused, so a hidden-textarea `execCommand` fallback keeps\n * the button working there rather than failing silently.\n */\nconst writeToClipboard = async (text: string): Promise<boolean> => {\n\ttry {\n\t\tif (navigator.clipboard?.writeText) {\n\t\t\tawait navigator.clipboard.writeText(text);\n\t\t\treturn true;\n\t\t}\n\t} catch {\n\t\t// Fall through to the legacy path.\n\t}\n\n\ttry {\n\t\tconst textarea = document.createElement('textarea');\n\t\ttextarea.value = text;\n\t\t// Off-screen rather than hidden: `display: none` cannot be selected.\n\t\ttextarea.setAttribute('readonly', '');\n\t\ttextarea.style.position = 'fixed';\n\t\ttextarea.style.top = '-1000px';\n\t\ttextarea.style.opacity = '0';\n\t\tdocument.body.appendChild(textarea);\n\t\ttextarea.select();\n\t\tconst copied = document.execCommand('copy');\n\t\tdocument.body.removeChild(textarea);\n\t\treturn copied;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\n/** How close to the top counts as asking for the previous page. */\nconst NEAR_TOP_TOLERANCE_PX = 48;\n\nconst SendArrowIcon = () => (\n\t<svg\n\t\tviewBox=\"0 0 24 24\"\n\t\twidth=\"16\"\n\t\theight=\"16\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t<path d=\"M12 19V5\" />\n\t\t<path d=\"M6 11l6-6 6 6\" />\n\t</svg>\n);\n\nconst ArrowRightIcon = () => (\n\t<svg\n\t\tviewBox=\"0 0 24 24\"\n\t\twidth=\"14\"\n\t\theight=\"14\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t<path d=\"M5 12h14\" />\n\t\t<path d=\"M13 6l6 6-6 6\" />\n\t</svg>\n);\n\nconst StopIcon = ({ size = 16 }: { size?: number }) => (\n\t<svg\n\t\tviewBox=\"0 0 24 24\"\n\t\twidth={size}\n\t\theight={size}\n\t\tfill=\"currentColor\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t<rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"2\" />\n\t</svg>\n);\n\nconst CopyIcon = () => (\n\t<svg\n\t\tviewBox=\"0 0 24 24\"\n\t\twidth=\"14\"\n\t\theight=\"14\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"1.8\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t<rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n\t\t<path d=\"M15 5.5A1.5 1.5 0 0 0 13.5 4H5.5A1.5 1.5 0 0 0 4 5.5v8A1.5 1.5 0 0 0 5.5 15\" />\n\t</svg>\n);\n\nconst CheckIcon = () => (\n\t<svg\n\t\tviewBox=\"0 0 24 24\"\n\t\twidth=\"14\"\n\t\theight=\"14\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2.2\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t<path d=\"M5 13l4 4L19 7\" />\n\t</svg>\n);\n\nconst ChevronDownIcon = () => (\n\t<svg\n\t\tviewBox=\"0 0 24 24\"\n\t\twidth=\"14\"\n\t\theight=\"14\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2.5\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t<path d=\"M6 9l6 6 6-6\" />\n\t</svg>\n);\n\n/**\n * Chat panel used by the copilot. Fully presentational: it renders the\n * transcript it is given and reports user intent through callbacks, so it works\n * against any backend.\n */\nexport const CopilotPanel: React.FC<CopilotPanelProps> = ({\n\tmessages,\n\tonSend,\n\tonClose,\n\ttitle = 'Copilot',\n\tbadge,\n\tsubtitle,\n\tavatar,\n\tplaceholder = 'Write your message...',\n\tdisclaimer = 'AI can make mistakes, Verify the responses.',\n\temptyStateTitle,\n\temptyStateSubtitle = 'Here are some things you can try',\n\tsuggestions,\n\tonSuggestionClick,\n\tshowRefresh = true,\n\tonRefresh,\n\tisThinking = false,\n\tthinkingLabel = 'Thinking',\n\tisStreaming = false,\n\tonStop,\n\tinterruptedLabel = 'This message was interrupted',\n\tfollowUpsLabel = 'Follow ups',\n\thasMoreHistory = false,\n\tisLoadingHistory = false,\n\tonLoadOlderMessages,\n\thistoryLoadingLabel = 'Loading earlier messages',\n\tinputDisabled = false,\n\terrorMessage,\n\twidth,\n\theight,\n\tclassName,\n\tstyle,\n}) => {\n\tconst [input, setInput] = useState('');\n\tconst [isInputFocused, setIsInputFocused] = useState(false);\n\tconst [isAtLatest, setIsAtLatest] = useState(true);\n\t// Which reply is showing \"Copied\" — per message, so copying one does not tick\n\t// the button under another.\n\tconst [copiedMessageId, setCopiedMessageId] = useState<string | null>(null);\n\tconst inputRef = useRef<HTMLTextAreaElement>(null);\n\tconst copiedTimeoutRef = useRef<number | null>(null);\n\tconst bottomRef = useRef<HTMLDivElement>(null);\n\tconst scrollerRef = useRef<HTMLDivElement>(null);\n\tconst lastScrollTopRef = useRef(0);\n\t// Distance from the bottom at the moment an older page was asked for. Older\n\t// messages land *above* the viewport, so without restoring against this the\n\t// content under the reader jumps down by the height of what arrived.\n\tconst anchorFromBottomRef = useRef<number | null>(null);\n\n\t// An assistant bubble is pushed the moment a turn starts, before any text has\n\t// arrived; the thinking indicator stands in for it until then, so rendering it\n\t// too would show an empty balloon next to the dots. A turn stopped before its\n\t// first token keeps its place, carrying only the interrupted note.\n\tconst visibleMessages = messages.filter(\n\t\t(message) => message.content.length > 0 || message.wasInterrupted,\n\t);\n\tconst isEmpty = visibleMessages.length === 0 && !isThinking;\n\tconst isTurnInFlight = isThinking || isStreaming;\n\tconst canSend = !inputDisabled && !isTurnInFlight && input.trim().length > 0;\n\t// Stopping is the only thing the button can do mid-answer, so it becomes the\n\t// stop button rather than sitting there disabled.\n\tconst canStop = isTurnInFlight && Boolean(onStop);\n\t// Only the newest reply's suggestions are on offer — older ones answer a\n\t// question the conversation has already moved past.\n\tconst newestMessage = visibleMessages[visibleMessages.length - 1];\n\tconst followUps =\n\t\t!isTurnInFlight && newestMessage?.role === 'assistant'\n\t\t\t? newestMessage.followUps\n\t\t\t: undefined;\n\t// A long answer that the reader has scrolled up from: the tail is clipped, so\n\t// the fade and the arrow say there is more below.\n\tconst showScrollAffordance = !isEmpty && !isAtLatest;\n\n\t// Following the conversation is the default, but a reader who has scrolled up\n\t// mid-answer must not be yanked back down by the next chunk.\n\tuseEffect(() => {\n\t\tif (!isAtLatest) {\n\t\t\treturn;\n\t\t}\n\t\tbottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n\t}, [messages, isThinking, isAtLatest]);\n\n\t// Older messages have landed: put the reader back on the message they were\n\t// looking at, which is now that much further down.\n\tuseEffect(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tconst anchor = anchorFromBottomRef.current;\n\t\tif (!scroller || anchor === null || isLoadingHistory) {\n\t\t\treturn;\n\t\t}\n\t\tanchorFromBottomRef.current = null;\n\t\tscroller.scrollTop = scroller.scrollHeight - anchor;\n\t\tlastScrollTopRef.current = scroller.scrollTop;\n\t}, [messages, isLoadingHistory]);\n\n\tconst handleScroll = () => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller) {\n\t\t\treturn;\n\t\t}\n\t\tconst distanceFromBottom =\n\t\t\tscroller.scrollHeight - scroller.scrollTop - scroller.clientHeight;\n\n\t\t// Reaching the top asks for the page before this one. The threshold gives\n\t\t// the request a head start, so the page is usually there by the time the\n\t\t// reader arrives.\n\t\tif (\n\t\t\tscroller.scrollTop <= NEAR_TOP_TOLERANCE_PX &&\n\t\t\thasMoreHistory &&\n\t\t\t!isLoadingHistory &&\n\t\t\tonLoadOlderMessages\n\t\t) {\n\t\t\tanchorFromBottomRef.current = scroller.scrollHeight - scroller.scrollTop;\n\t\t\tonLoadOlderMessages();\n\t\t}\n\t\t// Scrolling *up* is the only thing that detaches from the latest message:\n\t\t// growing content also pushes the bottom away, and auto-scroll itself only\n\t\t// ever moves down, so distance alone would flap mid-stream.\n\t\tconst scrolledUp = scroller.scrollTop < lastScrollTopRef.current - 1;\n\t\tlastScrollTopRef.current = scroller.scrollTop;\n\n\t\tif (distanceFromBottom <= AT_BOTTOM_TOLERANCE_PX) {\n\t\t\tsetIsAtLatest(true);\n\t\t\treturn;\n\t\t}\n\t\tif (scrolledUp) {\n\t\t\tsetIsAtLatest(false);\n\t\t}\n\t};\n\n\tconst handleJumpToLatest = () => {\n\t\tsetIsAtLatest(true);\n\t\tbottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n\t};\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tif (copiedTimeoutRef.current) {\n\t\t\t\twindow.clearTimeout(copiedTimeoutRef.current);\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\n\tconst handleCopyMessage = async (\n\t\tmessage: CopilotPanelProps['messages'][number],\n\t) => {\n\t\t// The raw markdown, not the rendered HTML — that is what a reader wants to\n\t\t// paste into a doc or a ticket.\n\t\tconst copied = await writeToClipboard(message.content);\n\t\tif (!copied) {\n\t\t\treturn;\n\t\t}\n\t\tif (copiedTimeoutRef.current) {\n\t\t\twindow.clearTimeout(copiedTimeoutRef.current);\n\t\t}\n\t\tsetCopiedMessageId(message.id);\n\t\tcopiedTimeoutRef.current = window.setTimeout(\n\t\t\t() => setCopiedMessageId(null),\n\t\t\tCOPIED_FEEDBACK_MS,\n\t\t);\n\t};\n\n\tconst handleSend = () => {\n\t\tconst trimmed = input.trim();\n\t\tif (!trimmed || inputDisabled || isTurnInFlight) {\n\t\t\treturn;\n\t\t}\n\t\tonSend(trimmed);\n\t\tsetInput('');\n\t\tconst textarea = inputRef.current;\n\t\tif (textarea) {\n\t\t\ttextarea.style.height = 'auto';\n\t\t}\n\t};\n\n\tconst handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\tsetInput(event.target.value);\n\t\tconst textarea = event.target;\n\t\ttextarea.style.height = 'auto';\n\t\ttextarea.style.height = `${Math.min(\n\t\t\ttextarea.scrollHeight,\n\t\t\tMAX_INPUT_HEIGHT_PX,\n\t\t)}px`;\n\t};\n\n\tconst handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n\t\tif (event.key === 'Enter' && !event.shiftKey) {\n\t\t\tevent.preventDefault();\n\t\t\thandleSend();\n\t\t}\n\t};\n\n\tconst handleSuggestionClick = (\n\t\tsuggestion: NonNullable<CopilotPanelProps['suggestions']>[number],\n\t) => {\n\t\tif (inputDisabled || isTurnInFlight) {\n\t\t\treturn;\n\t\t}\n\t\tonSuggestionClick?.(suggestion);\n\t\tonSend(suggestion.text);\n\t};\n\n\tconst handleFollowUpClick = (followUp: string) => {\n\t\tif (inputDisabled || isTurnInFlight) {\n\t\t\treturn;\n\t\t}\n\t\tonSend(followUp);\n\t};\n\n\treturn (\n\t\t<PanelContainer\n\t\t\tclassName={className}\n\t\t\tstyle={{ width, height, ...style }}\n\t\t\trole=\"dialog\"\n\t\t\taria-label={title}\n\t\t>\n\t\t\t<PanelHeader>\n\t\t\t\t<HeaderAvatar>\n\t\t\t\t\t{avatar ?? <AiStarsIcon width={18} height={18} />}\n\t\t\t\t</HeaderAvatar>\n\t\t\t\t<HeaderText>\n\t\t\t\t\t<HeaderTitleRow>\n\t\t\t\t\t\t<TitleSmall>{title}</TitleSmall>\n\t\t\t\t\t\t{badge && <HeaderBadge>{badge}</HeaderBadge>}\n\t\t\t\t\t</HeaderTitleRow>\n\t\t\t\t\t{subtitle && (\n\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t{subtitle}\n\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t)}\n\t\t\t\t</HeaderText>\n\t\t\t\t<HeaderActions>\n\t\t\t\t\t{showRefresh && onRefresh && (\n\t\t\t\t\t\t<IconAction\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={onRefresh}\n\t\t\t\t\t\t\taria-label=\"Start a new conversation\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RefreshIcon width={16} height={16} />\n\t\t\t\t\t\t</IconAction>\n\t\t\t\t\t)}\n\t\t\t\t\t<IconAction\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\taria-label=\"Close copilot\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<CrossIcon width={18} height={18} />\n\t\t\t\t\t</IconAction>\n\t\t\t\t</HeaderActions>\n\t\t\t</PanelHeader>\n\n\t\t\t<MessagesViewport>\n\t\t\t\t<MessagesArea\n\t\t\t\t\tref={scrollerRef}\n\t\t\t\t\tonScroll={handleScroll}\n\t\t\t\t\trole=\"region\"\n\t\t\t\t\taria-label=\"Conversation\"\n\t\t\t\t>\n\t\t\t\t\t{isEmpty ? (\n\t\t\t\t\t\t<EmptyState>\n\t\t\t\t\t\t\t<EmptyStateIcon>\n\t\t\t\t\t\t\t\t<AiStarsIcon width={28} height={28} />\n\t\t\t\t\t\t\t</EmptyStateIcon>\n\t\t\t\t\t\t\t<BodySecondary style={{ fontWeight: 600 }}>\n\t\t\t\t\t\t\t\t{emptyStateTitle || title}\n\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t{emptyStateSubtitle && (\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\t\t{emptyStateSubtitle}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{suggestions && suggestions.length > 0 && (\n\t\t\t\t\t\t\t\t<SuggestionList>\n\t\t\t\t\t\t\t\t\t{suggestions.map((suggestion) => (\n\t\t\t\t\t\t\t\t\t\t<SuggestionChip\n\t\t\t\t\t\t\t\t\t\t\tkey={suggestion.id}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tdisabled={inputDisabled || isTurnInFlight}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleSuggestionClick(suggestion)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<AiStarsIcon width={14} height={14} />\n\t\t\t\t\t\t\t\t\t\t\t{suggestion.text}\n\t\t\t\t\t\t\t\t\t\t</SuggestionChip>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</SuggestionList>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</EmptyState>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{isLoadingHistory && (\n\t\t\t\t\t\t\t\t<HistoryLoader role=\"status\" aria-live=\"polite\">\n\t\t\t\t\t\t\t\t\t<DotPulse color={COLORS.content.placeholder} size={4} />\n\t\t\t\t\t\t\t\t\t{historyLoadingLabel}\n\t\t\t\t\t\t\t\t</HistoryLoader>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{visibleMessages.map((message) => (\n\t\t\t\t\t\t\t\t<React.Fragment key={message.id}>\n\t\t\t\t\t\t\t\t\t{message.content.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t<MessageBubble $role={message.role}>\n\t\t\t\t\t\t\t\t\t\t\t{message.role === 'assistant' ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t__html: renderMarkdownLite(message.content),\n\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<div style={{ whiteSpace: 'pre-wrap' }}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{message.content}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</MessageBubble>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{message.wasInterrupted && interruptedLabel && (\n\t\t\t\t\t\t\t\t\t\t<InterruptedNote>\n\t\t\t\t\t\t\t\t\t\t\t<StopIcon size={12} />\n\t\t\t\t\t\t\t\t\t\t\t{interruptedLabel}\n\t\t\t\t\t\t\t\t\t\t</InterruptedNote>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{/* Only under a finished reply: mid-stream the text is still\n\t\t\t\t\t\t\t\t\t changing, so copying it would capture a partial answer. */}\n\t\t\t\t\t\t\t\t\t{message.role === 'assistant' &&\n\t\t\t\t\t\t\t\t\t\tmessage.content.length > 0 &&\n\t\t\t\t\t\t\t\t\t\t!message.isStreaming && (\n\t\t\t\t\t\t\t\t\t\t\t<MessageActions>\n\t\t\t\t\t\t\t\t\t\t\t\t<MessageAction\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => void handleCopyMessage(message)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-copied={copiedMessageId === message.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcopiedMessageId === message.id ? 'Copied' : 'Copy'\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t// The label changes with the state, so a screen reader\n\t\t\t\t\t\t\t\t\t\t\t\t\t// hears the confirmation the tick shows visually.\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcopiedMessageId === message.id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? 'Response copied to clipboard'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: 'Copy response'\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{copiedMessageId === message.id ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<CheckIcon />\n\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<CopyIcon />\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t</MessageAction>\n\t\t\t\t\t\t\t\t\t\t\t</MessageActions>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</React.Fragment>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t{followUps && followUps.length > 0 && (\n\t\t\t\t\t\t\t\t<FollowUpList>\n\t\t\t\t\t\t\t\t\t{followUpsLabel && (\n\t\t\t\t\t\t\t\t\t\t<FollowUpsLabel>{followUpsLabel}</FollowUpsLabel>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{followUps.map((followUp) => (\n\t\t\t\t\t\t\t\t\t\t<FollowUpChip\n\t\t\t\t\t\t\t\t\t\t\tkey={followUp}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tdisabled={inputDisabled}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleFollowUpClick(followUp)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<ArrowRightIcon />\n\t\t\t\t\t\t\t\t\t\t\t{followUp}\n\t\t\t\t\t\t\t\t\t\t</FollowUpChip>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</FollowUpList>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{isThinking && (\n\t\t\t\t\t\t\t\t<ThinkingBubble role=\"status\" aria-live=\"polite\">\n\t\t\t\t\t\t\t\t\t<AiStarsIcon\n\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.brand}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t{thinkingLabel && (\n\t\t\t\t\t\t\t\t\t\t<ThinkingLabel>{thinkingLabel}</ThinkingLabel>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t<DotPulse color={COLORS.background.brand} size={5} />\n\t\t\t\t\t\t\t\t</ThinkingBubble>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<div ref={bottomRef} />\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t</MessagesArea>\n\n\t\t\t\t<ScrollFade $visible={showScrollAffordance} aria-hidden=\"true\" />\n\t\t\t\t<JumpToLatestButton\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t$visible={showScrollAffordance}\n\t\t\t\t\tonClick={handleJumpToLatest}\n\t\t\t\t\ttabIndex={showScrollAffordance ? 0 : -1}\n\t\t\t\t\taria-label=\"Scroll to the latest message\"\n\t\t\t\t>\n\t\t\t\t\t<ChevronDownIcon />\n\t\t\t\t</JumpToLatestButton>\n\t\t\t</MessagesViewport>\n\n\t\t\t{errorMessage && <ErrorBanner role=\"alert\">{errorMessage}</ErrorBanner>}\n\n\t\t\t<InputArea>\n\t\t\t\t<InputWrapper $focused={isInputFocused}>\n\t\t\t\t\t<MessageInput\n\t\t\t\t\t\tref={inputRef}\n\t\t\t\t\t\trows={1}\n\t\t\t\t\t\tvalue={input}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\tdisabled={inputDisabled}\n\t\t\t\t\t\tonChange={handleInputChange}\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\tonFocus={() => setIsInputFocused(true)}\n\t\t\t\t\t\tonBlur={() => setIsInputFocused(false)}\n\t\t\t\t\t/>\n\t\t\t\t\t<SendButton\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={canStop || canSend}\n\t\t\t\t\t\tdisabled={!canStop && !canSend}\n\t\t\t\t\t\tonClick={canStop ? onStop : handleSend}\n\t\t\t\t\t\taria-label={canStop ? 'Stop generating' : 'Send message'}\n\t\t\t\t\t>\n\t\t\t\t\t\t{canStop ? <StopIcon /> : <SendArrowIcon />}\n\t\t\t\t\t</SendButton>\n\t\t\t\t</InputWrapper>\n\t\t\t</InputArea>\n\n\t\t\t{disclaimer && <Disclaimer>{disclaimer}</Disclaimer>}\n\t\t</PanelContainer>\n\t);\n};\n\nexport default CopilotPanel;\n"],"names":["MAX_INPUT_HEIGHT_PX","AT_BOTTOM_TOLERANCE_PX","COPIED_FEEDBACK_MS","writeToClipboard","text","textarea","copied","NEAR_TOP_TOLERANCE_PX","SendArrowIcon","jsxs","jsx","ArrowRightIcon","StopIcon","size","CopyIcon","CheckIcon","ChevronDownIcon","CopilotPanel","messages","onSend","onClose","title","badge","subtitle","avatar","placeholder","disclaimer","emptyStateTitle","emptyStateSubtitle","suggestions","onSuggestionClick","showRefresh","onRefresh","isThinking","thinkingLabel","isStreaming","onStop","interruptedLabel","followUpsLabel","hasMoreHistory","isLoadingHistory","onLoadOlderMessages","historyLoadingLabel","inputDisabled","errorMessage","width","height","className","style","input","setInput","useState","isInputFocused","setIsInputFocused","isAtLatest","setIsAtLatest","copiedMessageId","setCopiedMessageId","inputRef","useRef","copiedTimeoutRef","bottomRef","scrollerRef","lastScrollTopRef","anchorFromBottomRef","visibleMessages","message","isEmpty","isTurnInFlight","canSend","canStop","newestMessage","followUps","showScrollAffordance","useEffect","scroller","anchor","handleScroll","distanceFromBottom","scrolledUp","handleJumpToLatest","handleCopyMessage","handleSend","trimmed","handleInputChange","event","handleKeyDown","handleSuggestionClick","suggestion","handleFollowUpClick","followUp","PanelContainer","PanelHeader","HeaderAvatar","AiStarsIcon","HeaderText","HeaderTitleRow","TitleSmall","HeaderBadge","BodyCaption","COLORS","HeaderActions","IconAction","RefreshIcon","CrossIcon","MessagesViewport","MessagesArea","EmptyState","EmptyStateIcon","BodySecondary","SuggestionList","SuggestionChip","Fragment","HistoryLoader","DotPulse","React","MessageBubble","renderMarkdownLite","InterruptedNote","MessageActions","MessageAction","FollowUpList","FollowUpsLabel","FollowUpChip","ThinkingBubble","ThinkingLabel","ScrollFade","JumpToLatestButton","ErrorBanner","InputArea","InputWrapper","MessageInput","SendButton","Disclaimer"],"mappings":"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"}