@kweaver-ai/chatkit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +528 -0
- package/dist/chatkit.cjs.js +66 -0
- package/dist/chatkit.es.js +2966 -0
- package/dist/components/base/ChatKitBase.d.ts +261 -0
- package/dist/components/base/assistant/AssistantBase.d.ts +17 -0
- package/dist/components/base/assistant/Header.d.ts +20 -0
- package/dist/components/base/assistant/InputArea.d.ts +29 -0
- package/dist/components/base/assistant/MessageItem.d.ts +15 -0
- package/dist/components/base/assistant/MessageList.d.ts +15 -0
- package/dist/components/base/assistant/Prologue.d.ts +18 -0
- package/dist/components/base/assistant/blocks/MarkdownBlock.d.ts +15 -0
- package/dist/components/base/assistant/blocks/TextBlock.d.ts +15 -0
- package/dist/components/base/assistant/blocks/ToolBlock.d.ts +16 -0
- package/dist/components/base/assistant/blocks/ToolDrawer.d.ts +26 -0
- package/dist/components/base/assistant/blocks/WebSearchBlock.d.ts +16 -0
- package/dist/components/base/assistant/blocks/index.d.ts +9 -0
- package/dist/components/base/copilot/CopilotBase.d.ts +16 -0
- package/dist/components/base/copilot/Header.d.ts +22 -0
- package/dist/components/base/copilot/InputArea.d.ts +29 -0
- package/dist/components/base/copilot/MessageItem.d.ts +15 -0
- package/dist/components/base/copilot/MessageList.d.ts +15 -0
- package/dist/components/base/copilot/Prologue.d.ts +18 -0
- package/dist/components/base/copilot/blocks/MarkdownBlock.d.ts +15 -0
- package/dist/components/base/copilot/blocks/TextBlock.d.ts +15 -0
- package/dist/components/base/copilot/blocks/ToolBlock.d.ts +16 -0
- package/dist/components/base/copilot/blocks/ToolDrawer.d.ts +26 -0
- package/dist/components/base/copilot/blocks/WebSearchBlock.d.ts +16 -0
- package/dist/components/base/copilot/blocks/index.d.ts +9 -0
- package/dist/components/coze/Copilot.d.ts +102 -0
- package/dist/components/dip/Assistant.d.ts +22 -0
- package/dist/components/dip/Copilot.d.ts +22 -0
- package/dist/components/dip/DIPBase.d.ts +310 -0
- package/dist/components/icons/ClockIcon.d.ts +6 -0
- package/dist/components/icons/CloseIcon.d.ts +6 -0
- package/dist/components/icons/SendIcon.d.ts +13 -0
- package/dist/components/icons/StopIcon.d.ts +6 -0
- package/dist/components/icons/index.d.ts +7 -0
- package/dist/icons/assistant.svg +14 -0
- package/dist/icons/close.svg +6 -0
- package/dist/icons/expand.svg +3 -0
- package/dist/icons/more.svg +3 -0
- package/dist/icons/new.svg +10 -0
- package/dist/icons/send.svg +4 -0
- package/dist/index.d.ts +20 -0
- package/dist/types/index.d.ts +285 -0
- package/dist/utils/mixins.d.ts +18 -0
- package/package.json +66 -0
|
@@ -0,0 +1,2966 @@
|
|
|
1
|
+
(function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode('*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\\!visible{visibility:visible!important}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-0{bottom:0}.bottom-3{bottom:.75rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-1{left:.25rem}.left-\\[23px\\]{left:23px}.left-\\[40px\\]{left:40px}.right-0{right:0}.right-1{right:.25rem}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-1\\/2{top:50%}.top-3{top:.75rem}.top-4{top:1rem}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-10{margin-bottom:2.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-\\[14px\\]{margin-bottom:14px}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-1\\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-\\[13px\\]{height:13px}.h-\\[14px\\]{height:14px}.h-\\[16px\\]{height:16px}.h-\\[21px\\]{height:21px}.h-\\[36px\\]{height:36px}.h-\\[48px\\]{height:48px}.h-\\[56px\\]{height:56px}.h-\\[64px\\]{height:64px}.h-\\[76px\\]{height:76px}.h-\\[calc\\(100\\%-64px\\)\\]{height:calc(100% - 64px)}.h-full{height:100%}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-72{width:18rem}.w-8{width:2rem}.w-\\[14px\\]{width:14px}.w-\\[16px\\]{width:16px}.w-\\[21px\\]{width:21px}.w-\\[400px\\]{width:400px}.w-\\[440px\\]{width:440px}.w-\\[466px\\]{width:466px}.w-\\[480px\\]{width:480px}.w-\\[48px\\]{width:48px}.w-\\[600px\\]{width:600px}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-\\[90vw\\]{max-width:90vw}.max-w-\\[92vw\\]{max-width:92vw}.max-w-\\[960px\\]{max-width:960px}.max-w-\\[calc\\(100\\%-40px\\)\\]{max-width:calc(100% - 40px)}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.-translate-y-1\\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-\\[8px\\]{gap:8px}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-\\[2px\\]>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2px * var(--tw-space-y-reverse))}.self-end{align-self:flex-end}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\\[12px\\]{border-radius:12px}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-\\[1\\.5px\\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-solid{border-style:solid}.border-\\[\\#3b9be0\\]{--tw-border-opacity: 1;border-color:rgb(59 155 224 / var(--tw-border-opacity, 1))}.border-\\[\\#d9d9d9\\]{--tw-border-opacity: 1;border-color:rgb(217 217 217 / var(--tw-border-opacity, 1))}.border-\\[rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{border-color:#0000001a}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-900{--tw-border-opacity: 1;border-color:rgb(17 24 39 / var(--tw-border-opacity, 1))}.border-green-500{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.border-indigo-500{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.border-purple-500{--tw-border-opacity: 1;border-color:rgb(168 85 247 / var(--tw-border-opacity, 1))}.bg-\\[\\#52c41a\\]{--tw-bg-opacity: 1;background-color:rgb(82 196 26 / var(--tw-bg-opacity, 1))}.bg-\\[\\#f0f0f0\\]{--tw-bg-opacity: 1;background-color:rgb(240 240 240 / var(--tw-bg-opacity, 1))}.bg-\\[rgba\\(18\\,110\\,227\\,0\\.04\\)\\]{background-color:#126ee30a}.bg-\\[rgba\\(18\\,110\\,227\\,0\\.1\\)\\]{background-color:#126ee31a}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-500{--tw-bg-opacity: 1;background-color:rgb(107 114 128 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-indigo-50{--tw-bg-opacity: 1;background-color:rgb(238 242 255 / var(--tw-bg-opacity, 1))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-purple-50{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-\\[10px\\]{padding-left:10px;padding-right:10px}.px-\\[14px\\]{padding-left:14px;padding-right:14px}.px-\\[24px\\]{padding-left:24px;padding-right:24px}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\\[14px\\]{padding-top:14px;padding-bottom:14px}.py-\\[5px\\]{padding-top:5px;padding-bottom:5px}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pt-28{padding-top:7rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\\[12px\\]{font-size:12px}.text-\\[14px\\]{font-size:14px}.text-\\[16px\\]{font-size:16px}.text-\\[18px\\]{font-size:18px}.text-\\[20px\\]{font-size:20px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.leading-4{line-height:1rem}.leading-6{line-height:1.5rem}.leading-\\[17px\\]{line-height:17px}.leading-\\[18px\\]{line-height:18px}.leading-\\[22px\\]{line-height:22px}.leading-\\[24px\\]{line-height:24px}.leading-\\[30px\\]{line-height:30px}.leading-normal{line-height:1.5}.text-\\[rgba\\(0\\,0\\,0\\,0\\.45\\)\\]{color:#00000073}.text-\\[rgba\\(0\\,0\\,0\\,0\\.55\\)\\]{color:#0000008c}.text-\\[rgba\\(0\\,0\\,0\\,0\\.65\\)\\]{color:#000000a6}.text-\\[rgba\\(0\\,0\\,0\\,0\\.85\\)\\]{color:#000000d9}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-indigo-800{--tw-text-opacity: 1;color:rgb(55 48 163 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\\[0px_9px_56px_0px_rgba\\(0\\,0\\,0\\,0\\.08\\)\\]{--tw-shadow: 0px 9px 56px 0px rgba(0,0,0,.08);--tw-shadow-colored: 0px 9px 56px 0px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#555}.markdown-body{word-break:break-word}.markdown-body p{margin:.25rem 0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{font-weight:600;margin:.5rem 0 .25rem;line-height:1.3}.markdown-body a{color:#2563eb;text-decoration:underline}.markdown-body blockquote{border-left:4px solid #e5e7eb;padding-left:.75rem;color:#4b5563;margin:.5rem 0}.markdown-body ul,.markdown-body ol{margin:.25rem 0 .5rem}.markdown-body table{width:100%;border-collapse:collapse;margin:.5rem 0;font-size:.875rem}.markdown-body table th,.markdown-body table td{border:1px solid #e5e7eb;padding:.5rem}.markdown-body code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.markdown-body pre{margin:.5rem 0}.placeholder\\:text-\\[rgba\\(0\\,0\\,0\\,0\\.25\\)\\]::-moz-placeholder{color:#00000040}.placeholder\\:text-\\[rgba\\(0\\,0\\,0\\,0\\.25\\)\\]::placeholder{color:#00000040}.placeholder\\:text-\\[rgba\\(0\\,0\\,0\\,0\\.3\\)\\]::-moz-placeholder{color:#0000004d}.placeholder\\:text-\\[rgba\\(0\\,0\\,0\\,0\\.3\\)\\]::placeholder{color:#0000004d}.hover\\:border-\\[\\#3b9be0\\]:hover{--tw-border-opacity: 1;border-color:rgb(59 155 224 / var(--tw-border-opacity, 1))}.hover\\:border-blue-200:hover{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.hover\\:border-green-200:hover{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.hover\\:border-indigo-200:hover{--tw-border-opacity: 1;border-color:rgb(199 210 254 / var(--tw-border-opacity, 1))}.hover\\:border-purple-200:hover{--tw-border-opacity: 1;border-color:rgb(233 213 255 / var(--tw-border-opacity, 1))}.hover\\:bg-\\[rgba\\(18\\,110\\,227\\,0\\.04\\)\\]:hover{background-color:#126ee30a}.hover\\:bg-blue-600:hover{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\\:bg-gray-600:hover{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.hover\\:bg-green-600:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.hover\\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity, 1))}.hover\\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\\:text-\\[\\#1890ff\\]:hover{--tw-text-opacity: 1;color:rgb(24 144 255 / var(--tw-text-opacity, 1))}.hover\\:text-\\[rgba\\(0\\,0\\,0\\,0\\.85\\)\\]:hover{color:#000000d9}.hover\\:text-red-500:hover{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.hover\\:opacity-70:hover{opacity:.7}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.disabled\\:opacity-30:disabled{opacity:.3}@media(min-width:768px){.md\\:pr-\\[500px\\]{padding-right:500px}}')),document.head.appendChild(t)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
|
|
2
|
+
var Tt = Object.defineProperty;
|
|
3
|
+
var _t = (c, p, l) => p in c ? Tt(c, p, { enumerable: !0, configurable: !0, writable: !0, value: l }) : c[p] = l;
|
|
4
|
+
var S = (c, p, l) => _t(c, typeof p != "symbol" ? p + "" : p, l);
|
|
5
|
+
import Me, { Component as Et, useEffect as F, useState as Be, useRef as Le } from "react";
|
|
6
|
+
import U from "react-markdown";
|
|
7
|
+
import z from "remark-gfm";
|
|
8
|
+
var P = /* @__PURE__ */ ((c) => (c.USER = "User", c.ASSISTANT = "Assistant", c))(P || {}), Rt = /* @__PURE__ */ ((c) => (c.TEXT = "Text", c.JSON = "JSON", c.WIDGET = "Widget", c))(Rt || {}), T = /* @__PURE__ */ ((c) => (c.TEXT = "Text", c.MARKDOWN = "Markdown", c.WEB_SEARCH = "WebSearch", c.TOOL = "Tool", c))(T || {});
|
|
9
|
+
class le extends Et {
|
|
10
|
+
constructor(l) {
|
|
11
|
+
super(l);
|
|
12
|
+
/**
|
|
13
|
+
* 标记是否正在初始化或已经初始化
|
|
14
|
+
* 用于防止重复初始化(特别是在 React.StrictMode 下)
|
|
15
|
+
*/
|
|
16
|
+
S(this, "isInitializing", !1);
|
|
17
|
+
S(this, "hasInitialized", !1);
|
|
18
|
+
/**
|
|
19
|
+
* 调用接口时携带的令牌
|
|
20
|
+
*/
|
|
21
|
+
S(this, "token");
|
|
22
|
+
/**
|
|
23
|
+
* 刷新 token 的方法,由集成方传入
|
|
24
|
+
*/
|
|
25
|
+
S(this, "refreshToken");
|
|
26
|
+
/**
|
|
27
|
+
* 向 ChatKit 注入应用上下文
|
|
28
|
+
* @param ctx 要注入的应用上下文
|
|
29
|
+
*/
|
|
30
|
+
S(this, "injectApplicationContext", (l) => {
|
|
31
|
+
this.setState({ applicationContext: l });
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* 移除注入的应用上下文
|
|
35
|
+
*/
|
|
36
|
+
S(this, "removeApplicationContext", () => {
|
|
37
|
+
this.setState({ applicationContext: this.props.defaultApplicationContext });
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* 创建新的会话
|
|
41
|
+
* 内部会调用子类实现的 generateConversation() 和 getOnboardingInfo() 方法
|
|
42
|
+
*/
|
|
43
|
+
S(this, "createConversation", async () => {
|
|
44
|
+
this.setState({ isLoadingOnboarding: !0 });
|
|
45
|
+
try {
|
|
46
|
+
this.clearConversation();
|
|
47
|
+
const l = await this.generateConversation(), e = await this.getOnboardingInfo();
|
|
48
|
+
this.setState({
|
|
49
|
+
conversationID: l,
|
|
50
|
+
onboardingInfo: e
|
|
51
|
+
}), console.log("新会话已创建, conversationID:", l), console.log("开场白信息已加载:", e);
|
|
52
|
+
} catch (l) {
|
|
53
|
+
throw console.error("创建新会话失败:", l), l;
|
|
54
|
+
} finally {
|
|
55
|
+
this.setState({ isLoadingOnboarding: !1 });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* 加载历史会话
|
|
60
|
+
* 该方法从后端加载指定 ID 的历史会话消息,并更新到组件状态中
|
|
61
|
+
* @param conversationId 要加载的会话 ID
|
|
62
|
+
*/
|
|
63
|
+
S(this, "loadConversation", async (l) => {
|
|
64
|
+
try {
|
|
65
|
+
const e = await this.getConversationMessages(l);
|
|
66
|
+
this.setState({
|
|
67
|
+
conversationID: l,
|
|
68
|
+
messages: e,
|
|
69
|
+
onboardingInfo: void 0
|
|
70
|
+
// 清除开场白信息
|
|
71
|
+
}), console.log("历史会话已加载, conversationID:", l), console.log("加载了", e.length, "条消息");
|
|
72
|
+
} catch (e) {
|
|
73
|
+
throw console.error("加载历史会话失败:", e), e;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* 清除会话中的对话消息及会话 ID
|
|
78
|
+
*/
|
|
79
|
+
S(this, "clearConversation", () => {
|
|
80
|
+
this.setState({
|
|
81
|
+
conversationID: "",
|
|
82
|
+
messages: []
|
|
83
|
+
}), console.log("会话已清除");
|
|
84
|
+
});
|
|
85
|
+
/**
|
|
86
|
+
* 发送消息的核心方法
|
|
87
|
+
* 该方法是暴露给集成方进行调用的接口,内部会调用子类实现的 sendMessage() 方法
|
|
88
|
+
* @param text 用户输入的文本
|
|
89
|
+
* @param ctx 应用上下文
|
|
90
|
+
* @param conversationID 发送的对话消息所属的会话 ID(可选)
|
|
91
|
+
* @returns 返回发送的消息结构
|
|
92
|
+
*/
|
|
93
|
+
S(this, "send", async (l, e, s) => {
|
|
94
|
+
if (!l.trim())
|
|
95
|
+
throw new Error("消息内容不能为空");
|
|
96
|
+
e && this.setState({ applicationContext: e });
|
|
97
|
+
let n = s || this.state.conversationID;
|
|
98
|
+
if (!n)
|
|
99
|
+
try {
|
|
100
|
+
n = await this.generateConversation(), this.setState({ conversationID: n }), console.log("自动创建新会话, conversationID:", n);
|
|
101
|
+
} catch (i) {
|
|
102
|
+
console.error("自动创建会话失败:", i);
|
|
103
|
+
}
|
|
104
|
+
this.setState({ isSending: !0 });
|
|
105
|
+
const o = e || this.state.applicationContext || this.props.defaultApplicationContext || { title: "", data: {} }, a = {
|
|
106
|
+
messageId: `user-${Date.now()}`,
|
|
107
|
+
content: [
|
|
108
|
+
{
|
|
109
|
+
type: T.TEXT,
|
|
110
|
+
content: l
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
role: {
|
|
114
|
+
name: "用户",
|
|
115
|
+
type: P.USER,
|
|
116
|
+
avatar: ""
|
|
117
|
+
},
|
|
118
|
+
// 如果有应用上下文,则附加到用户消息中
|
|
119
|
+
applicationContext: o.title || o.data ? o : void 0
|
|
120
|
+
};
|
|
121
|
+
this.setState((i) => ({
|
|
122
|
+
messages: [...i.messages, a]
|
|
123
|
+
}));
|
|
124
|
+
try {
|
|
125
|
+
const i = await this.sendMessage(l, o, n);
|
|
126
|
+
return this.setState({
|
|
127
|
+
textInput: "",
|
|
128
|
+
isSending: !1,
|
|
129
|
+
streamingMessageId: null
|
|
130
|
+
}), i;
|
|
131
|
+
} catch (i) {
|
|
132
|
+
throw console.error("发送消息失败:", i), this.setState({ isSending: !1, streamingMessageId: null }), i;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
/**
|
|
136
|
+
* 处理发送按钮点击
|
|
137
|
+
*/
|
|
138
|
+
S(this, "handleSend", async () => {
|
|
139
|
+
if (!this.state.textInput.trim() || this.state.isSending)
|
|
140
|
+
return;
|
|
141
|
+
const l = this.state.applicationContext || this.props.defaultApplicationContext || { title: "", data: {} };
|
|
142
|
+
console.log("发送消息:", this.state.textInput), console.log("选中的上下文:", l);
|
|
143
|
+
try {
|
|
144
|
+
await this.send(this.state.textInput, l);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
console.error("发送消息失败:", e);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* 处理停止流式响应
|
|
151
|
+
* 调用子类实现的 terminateConversation 方法终止当前会话
|
|
152
|
+
*/
|
|
153
|
+
S(this, "handleStop", async () => {
|
|
154
|
+
const { conversationID: l, streamingMessageId: e } = this.state;
|
|
155
|
+
if (!e) {
|
|
156
|
+
console.warn("没有正在进行的流式响应");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
console.log("停止流式响应, conversationID:", l);
|
|
160
|
+
try {
|
|
161
|
+
await this.terminateConversation(l), this.setState({
|
|
162
|
+
streamingMessageId: null,
|
|
163
|
+
isSending: !1
|
|
164
|
+
}), console.log("流式响应已停止");
|
|
165
|
+
} catch (s) {
|
|
166
|
+
console.error("停止流式响应失败:", s), this.setState({
|
|
167
|
+
streamingMessageId: null,
|
|
168
|
+
isSending: !1
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
/**
|
|
173
|
+
* 更新用户输入
|
|
174
|
+
*/
|
|
175
|
+
S(this, "setTextInput", (l) => {
|
|
176
|
+
this.setState({ textInput: l });
|
|
177
|
+
});
|
|
178
|
+
/**
|
|
179
|
+
* 处理推荐问题点击
|
|
180
|
+
*/
|
|
181
|
+
S(this, "handleQuestionClick", (l) => {
|
|
182
|
+
this.setState({ textInput: l });
|
|
183
|
+
});
|
|
184
|
+
this.token = l.token || "", this.refreshToken = l.refreshToken, this.state = {
|
|
185
|
+
conversationID: l.conversationID || "",
|
|
186
|
+
messages: [],
|
|
187
|
+
textInput: "",
|
|
188
|
+
applicationContext: l.defaultApplicationContext,
|
|
189
|
+
isSending: !1,
|
|
190
|
+
streamingMessageId: null,
|
|
191
|
+
onboardingInfo: void 0,
|
|
192
|
+
isLoadingOnboarding: !1
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 组件挂载后自动创建会话
|
|
197
|
+
* 根据设计文档要求:组件被初始化的时候会自动新建会话
|
|
198
|
+
*/
|
|
199
|
+
async componentDidMount() {
|
|
200
|
+
this.props.visible && !this.hasInitialized && !this.isInitializing && await this.initializeConversation();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* 组件更新时检查是否需要初始化会话
|
|
204
|
+
* 当 visible 从 false 变为 true 时,如果还未初始化,则初始化会话
|
|
205
|
+
*/
|
|
206
|
+
async componentDidUpdate(l) {
|
|
207
|
+
!l.visible && this.props.visible && !this.hasInitialized && !this.isInitializing && await this.initializeConversation();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 初始化会话的内部方法
|
|
211
|
+
* 仅在组件首次可见时调用,防止重复初始化
|
|
212
|
+
*/
|
|
213
|
+
async initializeConversation() {
|
|
214
|
+
if (this.isInitializing || this.hasInitialized) {
|
|
215
|
+
console.log("会话正在初始化或已初始化,跳过");
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
this.isInitializing = !0, this.setState({ isLoadingOnboarding: !0 });
|
|
219
|
+
try {
|
|
220
|
+
console.log("ChatKit 组件初始化,自动创建会话..."), await this.createConversation(), this.hasInitialized = !0;
|
|
221
|
+
} catch (l) {
|
|
222
|
+
console.error("自动创建会话失败:", l);
|
|
223
|
+
try {
|
|
224
|
+
const e = await this.getOnboardingInfo();
|
|
225
|
+
this.setState({ onboardingInfo: e }), this.hasInitialized = !0;
|
|
226
|
+
} catch (e) {
|
|
227
|
+
console.error("获取开场白信息失败:", e);
|
|
228
|
+
}
|
|
229
|
+
} finally {
|
|
230
|
+
this.isInitializing = !1, this.setState({ isLoadingOnboarding: !1 });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* 添加或更新 Markdown 类型的消息块
|
|
235
|
+
* 该方法由子类调用,用于在消息中添加或更新 Markdown 内容块
|
|
236
|
+
* 如果最后一个块是 Markdown 块且内容为空或是 text 的前缀,则更新它(流式更新场景)
|
|
237
|
+
* 否则添加新的 Markdown 块(新阶段场景)
|
|
238
|
+
* @param messageId 消息 ID
|
|
239
|
+
* @param text 要添加或更新的 Markdown 文本,每次都传完整的文本
|
|
240
|
+
*/
|
|
241
|
+
appendMarkdownBlock(l, e) {
|
|
242
|
+
this.setState((s) => ({ messages: s.messages.map((o) => {
|
|
243
|
+
if (o.messageId === l) {
|
|
244
|
+
const a = o.content.length > 0 ? o.content[o.content.length - 1] : null;
|
|
245
|
+
let i;
|
|
246
|
+
return a && a.type === T.MARKDOWN && (a.content === "" || e.startsWith(a.content)) ? (i = [...o.content], i[i.length - 1] = {
|
|
247
|
+
type: T.MARKDOWN,
|
|
248
|
+
content: e
|
|
249
|
+
}) : i = [
|
|
250
|
+
...o.content,
|
|
251
|
+
{
|
|
252
|
+
type: T.MARKDOWN,
|
|
253
|
+
content: e
|
|
254
|
+
}
|
|
255
|
+
], { ...o, content: i };
|
|
256
|
+
}
|
|
257
|
+
return o;
|
|
258
|
+
}) }));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* 添加 Web 搜索类型的消息块
|
|
262
|
+
* 该方法由子类调用,用于在消息中添加 Web 搜索结果
|
|
263
|
+
* @param messageId 消息 ID
|
|
264
|
+
* @param query Web 搜索的执行详情
|
|
265
|
+
*/
|
|
266
|
+
appendWebSearchBlock(l, e) {
|
|
267
|
+
this.setState((s) => ({ messages: s.messages.map((o) => {
|
|
268
|
+
if (o.messageId === l) {
|
|
269
|
+
const a = [
|
|
270
|
+
...o.content,
|
|
271
|
+
{
|
|
272
|
+
type: T.WEB_SEARCH,
|
|
273
|
+
content: e
|
|
274
|
+
}
|
|
275
|
+
];
|
|
276
|
+
return { ...o, content: a };
|
|
277
|
+
}
|
|
278
|
+
return o;
|
|
279
|
+
}) }));
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* 添加代码执行工具类型的消息块
|
|
283
|
+
* 该方法由子类调用,用于在消息中添加代码执行结果
|
|
284
|
+
* @param messageId 消息 ID
|
|
285
|
+
* @param result 代码执行的输入和输出结果
|
|
286
|
+
*/
|
|
287
|
+
appendExecuteCodeBlock(l, e) {
|
|
288
|
+
this.setState((s) => ({ messages: s.messages.map((o) => {
|
|
289
|
+
if (o.messageId === l) {
|
|
290
|
+
const a = [
|
|
291
|
+
...o.content,
|
|
292
|
+
{
|
|
293
|
+
type: T.TOOL,
|
|
294
|
+
content: {
|
|
295
|
+
name: "execute_code",
|
|
296
|
+
title: "代码执行",
|
|
297
|
+
input: e.input,
|
|
298
|
+
output: e.output
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
];
|
|
302
|
+
return { ...o, content: a };
|
|
303
|
+
}
|
|
304
|
+
return o;
|
|
305
|
+
}) }));
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* 处理流式响应
|
|
309
|
+
* 在闭包中处理 EventStream,并在处理完成后丢弃闭包
|
|
310
|
+
* @param reader ReadableStreamDefaultReader
|
|
311
|
+
* @param assistantMessageId 助手消息 ID
|
|
312
|
+
*/
|
|
313
|
+
async handleStreamResponse(l, e) {
|
|
314
|
+
const s = new TextDecoder();
|
|
315
|
+
let n = {};
|
|
316
|
+
try {
|
|
317
|
+
let o = "", a = "";
|
|
318
|
+
for (; ; ) {
|
|
319
|
+
const { done: i, value: d } = await l.read();
|
|
320
|
+
if (i) {
|
|
321
|
+
console.log("流式响应完成");
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
const u = s.decode(d, { stream: !0 });
|
|
325
|
+
a += u;
|
|
326
|
+
const x = a.split(`
|
|
327
|
+
`);
|
|
328
|
+
a = x.pop() || "";
|
|
329
|
+
for (const f of x) {
|
|
330
|
+
const m = f.trim();
|
|
331
|
+
if (m) {
|
|
332
|
+
if (m.startsWith("event:")) {
|
|
333
|
+
o = m.slice(6).trim(), console.log("收到SSE event:", o);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
if (m.startsWith("data:")) {
|
|
337
|
+
const y = m.slice(5).trim();
|
|
338
|
+
if (y === "[DONE]") {
|
|
339
|
+
console.log("收到 DONE 标记");
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const b = JSON.parse(y);
|
|
344
|
+
console.log("收到SSE数据:", b);
|
|
345
|
+
const N = {
|
|
346
|
+
event: o || b.event || b.type || "",
|
|
347
|
+
data: y
|
|
348
|
+
};
|
|
349
|
+
console.log("构造的 EventStreamMessage:", N), n = this.reduceAssistantMessage(
|
|
350
|
+
N,
|
|
351
|
+
n,
|
|
352
|
+
e
|
|
353
|
+
), o = "";
|
|
354
|
+
} catch (b) {
|
|
355
|
+
console.error("解析流式响应失败:", b, "原始数据长度:", y.length), console.error("数据前100字符:", y.substring(0, 100)), console.error("数据后100字符:", y.substring(Math.max(0, y.length - 100)));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
a.trim() && console.log("处理剩余缓冲区数据:", a);
|
|
362
|
+
} finally {
|
|
363
|
+
l.releaseLock();
|
|
364
|
+
}
|
|
365
|
+
return n;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* 执行 API 调用,并在需要时自动刷新 token 并重试一次
|
|
369
|
+
* @param apiCall API 调用函数
|
|
370
|
+
* @returns API 调用结果
|
|
371
|
+
*/
|
|
372
|
+
async executeWithTokenRefresh(l) {
|
|
373
|
+
var e, s, n, o;
|
|
374
|
+
try {
|
|
375
|
+
return await l();
|
|
376
|
+
} catch (a) {
|
|
377
|
+
const i = a.status || ((e = a.response) == null ? void 0 : e.status) || 0, d = a.body || ((s = a.response) == null ? void 0 : s.data) || a;
|
|
378
|
+
if (this.shouldRefreshToken(i, d) && this.refreshToken) {
|
|
379
|
+
console.log("检测到 token 失效,正在刷新 token...");
|
|
380
|
+
try {
|
|
381
|
+
const x = await this.refreshToken();
|
|
382
|
+
this.token = x, console.log("Token 刷新成功,正在重试请求...");
|
|
383
|
+
try {
|
|
384
|
+
return await l();
|
|
385
|
+
} catch (f) {
|
|
386
|
+
const m = f.status || ((n = f.response) == null ? void 0 : n.status) || 0, y = f.body || ((o = f.response) == null ? void 0 : o.data) || f;
|
|
387
|
+
throw this.shouldRefreshToken(m, y) && console.error("重试后仍然提示 token 失效,放弃重试"), f;
|
|
388
|
+
}
|
|
389
|
+
} catch (x) {
|
|
390
|
+
throw console.error("刷新 token 失败:", x), a;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
throw a;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
var H = { exports: {} }, K = {};
|
|
398
|
+
/**
|
|
399
|
+
* @license React
|
|
400
|
+
* react-jsx-runtime.production.min.js
|
|
401
|
+
*
|
|
402
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
403
|
+
*
|
|
404
|
+
* This source code is licensed under the MIT license found in the
|
|
405
|
+
* LICENSE file in the root directory of this source tree.
|
|
406
|
+
*/
|
|
407
|
+
var De;
|
|
408
|
+
function It() {
|
|
409
|
+
if (De) return K;
|
|
410
|
+
De = 1;
|
|
411
|
+
var c = Me, p = Symbol.for("react.element"), l = Symbol.for("react.fragment"), e = Object.prototype.hasOwnProperty, s = c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, n = { key: !0, ref: !0, __self: !0, __source: !0 };
|
|
412
|
+
function o(a, i, d) {
|
|
413
|
+
var u, x = {}, f = null, m = null;
|
|
414
|
+
d !== void 0 && (f = "" + d), i.key !== void 0 && (f = "" + i.key), i.ref !== void 0 && (m = i.ref);
|
|
415
|
+
for (u in i) e.call(i, u) && !n.hasOwnProperty(u) && (x[u] = i[u]);
|
|
416
|
+
if (a && a.defaultProps) for (u in i = a.defaultProps, i) x[u] === void 0 && (x[u] = i[u]);
|
|
417
|
+
return { $$typeof: p, type: a, key: f, ref: m, props: x, _owner: s.current };
|
|
418
|
+
}
|
|
419
|
+
return K.Fragment = l, K.jsx = o, K.jsxs = o, K;
|
|
420
|
+
}
|
|
421
|
+
var q = {};
|
|
422
|
+
/**
|
|
423
|
+
* @license React
|
|
424
|
+
* react-jsx-runtime.development.js
|
|
425
|
+
*
|
|
426
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
427
|
+
*
|
|
428
|
+
* This source code is licensed under the MIT license found in the
|
|
429
|
+
* LICENSE file in the root directory of this source tree.
|
|
430
|
+
*/
|
|
431
|
+
var $e;
|
|
432
|
+
function At() {
|
|
433
|
+
return $e || ($e = 1, process.env.NODE_ENV !== "production" && (function() {
|
|
434
|
+
var c = Me, p = Symbol.for("react.element"), l = Symbol.for("react.portal"), e = Symbol.for("react.fragment"), s = Symbol.for("react.strict_mode"), n = Symbol.for("react.profiler"), o = Symbol.for("react.provider"), a = Symbol.for("react.context"), i = Symbol.for("react.forward_ref"), d = Symbol.for("react.suspense"), u = Symbol.for("react.suspense_list"), x = Symbol.for("react.memo"), f = Symbol.for("react.lazy"), m = Symbol.for("react.offscreen"), y = Symbol.iterator, b = "@@iterator";
|
|
435
|
+
function N(r) {
|
|
436
|
+
if (r === null || typeof r != "object")
|
|
437
|
+
return null;
|
|
438
|
+
var h = y && r[y] || r[b];
|
|
439
|
+
return typeof h == "function" ? h : null;
|
|
440
|
+
}
|
|
441
|
+
var D = c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
442
|
+
function R(r) {
|
|
443
|
+
{
|
|
444
|
+
for (var h = arguments.length, g = new Array(h > 1 ? h - 1 : 0), v = 1; v < h; v++)
|
|
445
|
+
g[v - 1] = arguments[v];
|
|
446
|
+
Z("error", r, g);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
function Z(r, h, g) {
|
|
450
|
+
{
|
|
451
|
+
var v = D.ReactDebugCurrentFrame, k = v.getStackAddendum();
|
|
452
|
+
k !== "" && (h += "%s", g = g.concat([k]));
|
|
453
|
+
var C = g.map(function(j) {
|
|
454
|
+
return String(j);
|
|
455
|
+
});
|
|
456
|
+
C.unshift("Warning: " + h), Function.prototype.apply.call(console[r], console, C);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
var qe = !1, Qe = !1, Ye = !1, Xe = !1, Ge = !1, ce;
|
|
460
|
+
ce = Symbol.for("react.module.reference");
|
|
461
|
+
function He(r) {
|
|
462
|
+
return !!(typeof r == "string" || typeof r == "function" || r === e || r === n || Ge || r === s || r === d || r === u || Xe || r === m || qe || Qe || Ye || typeof r == "object" && r !== null && (r.$$typeof === f || r.$$typeof === x || r.$$typeof === o || r.$$typeof === a || r.$$typeof === i || // This needs to include all possible module reference object
|
|
463
|
+
// types supported by any Flight configuration anywhere since
|
|
464
|
+
// we don't know which Flight build this will end up being used
|
|
465
|
+
// with.
|
|
466
|
+
r.$$typeof === ce || r.getModuleId !== void 0));
|
|
467
|
+
}
|
|
468
|
+
function Ze(r, h, g) {
|
|
469
|
+
var v = r.displayName;
|
|
470
|
+
if (v)
|
|
471
|
+
return v;
|
|
472
|
+
var k = h.displayName || h.name || "";
|
|
473
|
+
return k !== "" ? g + "(" + k + ")" : g;
|
|
474
|
+
}
|
|
475
|
+
function de(r) {
|
|
476
|
+
return r.displayName || "Context";
|
|
477
|
+
}
|
|
478
|
+
function $(r) {
|
|
479
|
+
if (r == null)
|
|
480
|
+
return null;
|
|
481
|
+
if (typeof r.tag == "number" && R("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), typeof r == "function")
|
|
482
|
+
return r.displayName || r.name || null;
|
|
483
|
+
if (typeof r == "string")
|
|
484
|
+
return r;
|
|
485
|
+
switch (r) {
|
|
486
|
+
case e:
|
|
487
|
+
return "Fragment";
|
|
488
|
+
case l:
|
|
489
|
+
return "Portal";
|
|
490
|
+
case n:
|
|
491
|
+
return "Profiler";
|
|
492
|
+
case s:
|
|
493
|
+
return "StrictMode";
|
|
494
|
+
case d:
|
|
495
|
+
return "Suspense";
|
|
496
|
+
case u:
|
|
497
|
+
return "SuspenseList";
|
|
498
|
+
}
|
|
499
|
+
if (typeof r == "object")
|
|
500
|
+
switch (r.$$typeof) {
|
|
501
|
+
case a:
|
|
502
|
+
var h = r;
|
|
503
|
+
return de(h) + ".Consumer";
|
|
504
|
+
case o:
|
|
505
|
+
var g = r;
|
|
506
|
+
return de(g._context) + ".Provider";
|
|
507
|
+
case i:
|
|
508
|
+
return Ze(r, r.render, "ForwardRef");
|
|
509
|
+
case x:
|
|
510
|
+
var v = r.displayName || null;
|
|
511
|
+
return v !== null ? v : $(r.type) || "Memo";
|
|
512
|
+
case f: {
|
|
513
|
+
var k = r, C = k._payload, j = k._init;
|
|
514
|
+
try {
|
|
515
|
+
return $(j(C));
|
|
516
|
+
} catch {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
523
|
+
var M = Object.assign, J = 0, ue, he, fe, pe, xe, ge, me;
|
|
524
|
+
function ye() {
|
|
525
|
+
}
|
|
526
|
+
ye.__reactDisabledLog = !0;
|
|
527
|
+
function et() {
|
|
528
|
+
{
|
|
529
|
+
if (J === 0) {
|
|
530
|
+
ue = console.log, he = console.info, fe = console.warn, pe = console.error, xe = console.group, ge = console.groupCollapsed, me = console.groupEnd;
|
|
531
|
+
var r = {
|
|
532
|
+
configurable: !0,
|
|
533
|
+
enumerable: !0,
|
|
534
|
+
value: ye,
|
|
535
|
+
writable: !0
|
|
536
|
+
};
|
|
537
|
+
Object.defineProperties(console, {
|
|
538
|
+
info: r,
|
|
539
|
+
log: r,
|
|
540
|
+
warn: r,
|
|
541
|
+
error: r,
|
|
542
|
+
group: r,
|
|
543
|
+
groupCollapsed: r,
|
|
544
|
+
groupEnd: r
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
J++;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
function tt() {
|
|
551
|
+
{
|
|
552
|
+
if (J--, J === 0) {
|
|
553
|
+
var r = {
|
|
554
|
+
configurable: !0,
|
|
555
|
+
enumerable: !0,
|
|
556
|
+
writable: !0
|
|
557
|
+
};
|
|
558
|
+
Object.defineProperties(console, {
|
|
559
|
+
log: M({}, r, {
|
|
560
|
+
value: ue
|
|
561
|
+
}),
|
|
562
|
+
info: M({}, r, {
|
|
563
|
+
value: he
|
|
564
|
+
}),
|
|
565
|
+
warn: M({}, r, {
|
|
566
|
+
value: fe
|
|
567
|
+
}),
|
|
568
|
+
error: M({}, r, {
|
|
569
|
+
value: pe
|
|
570
|
+
}),
|
|
571
|
+
group: M({}, r, {
|
|
572
|
+
value: xe
|
|
573
|
+
}),
|
|
574
|
+
groupCollapsed: M({}, r, {
|
|
575
|
+
value: ge
|
|
576
|
+
}),
|
|
577
|
+
groupEnd: M({}, r, {
|
|
578
|
+
value: me
|
|
579
|
+
})
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
J < 0 && R("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
var ee = D.ReactCurrentDispatcher, te;
|
|
586
|
+
function Q(r, h, g) {
|
|
587
|
+
{
|
|
588
|
+
if (te === void 0)
|
|
589
|
+
try {
|
|
590
|
+
throw Error();
|
|
591
|
+
} catch (k) {
|
|
592
|
+
var v = k.stack.trim().match(/\n( *(at )?)/);
|
|
593
|
+
te = v && v[1] || "";
|
|
594
|
+
}
|
|
595
|
+
return `
|
|
596
|
+
` + te + r;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
var re = !1, Y;
|
|
600
|
+
{
|
|
601
|
+
var rt = typeof WeakMap == "function" ? WeakMap : Map;
|
|
602
|
+
Y = new rt();
|
|
603
|
+
}
|
|
604
|
+
function ve(r, h) {
|
|
605
|
+
if (!r || re)
|
|
606
|
+
return "";
|
|
607
|
+
{
|
|
608
|
+
var g = Y.get(r);
|
|
609
|
+
if (g !== void 0)
|
|
610
|
+
return g;
|
|
611
|
+
}
|
|
612
|
+
var v;
|
|
613
|
+
re = !0;
|
|
614
|
+
var k = Error.prepareStackTrace;
|
|
615
|
+
Error.prepareStackTrace = void 0;
|
|
616
|
+
var C;
|
|
617
|
+
C = ee.current, ee.current = null, et();
|
|
618
|
+
try {
|
|
619
|
+
if (h) {
|
|
620
|
+
var j = function() {
|
|
621
|
+
throw Error();
|
|
622
|
+
};
|
|
623
|
+
if (Object.defineProperty(j.prototype, "props", {
|
|
624
|
+
set: function() {
|
|
625
|
+
throw Error();
|
|
626
|
+
}
|
|
627
|
+
}), typeof Reflect == "object" && Reflect.construct) {
|
|
628
|
+
try {
|
|
629
|
+
Reflect.construct(j, []);
|
|
630
|
+
} catch (A) {
|
|
631
|
+
v = A;
|
|
632
|
+
}
|
|
633
|
+
Reflect.construct(r, [], j);
|
|
634
|
+
} else {
|
|
635
|
+
try {
|
|
636
|
+
j.call();
|
|
637
|
+
} catch (A) {
|
|
638
|
+
v = A;
|
|
639
|
+
}
|
|
640
|
+
r.call(j.prototype);
|
|
641
|
+
}
|
|
642
|
+
} else {
|
|
643
|
+
try {
|
|
644
|
+
throw Error();
|
|
645
|
+
} catch (A) {
|
|
646
|
+
v = A;
|
|
647
|
+
}
|
|
648
|
+
r();
|
|
649
|
+
}
|
|
650
|
+
} catch (A) {
|
|
651
|
+
if (A && v && typeof A.stack == "string") {
|
|
652
|
+
for (var w = A.stack.split(`
|
|
653
|
+
`), I = v.stack.split(`
|
|
654
|
+
`), _ = w.length - 1, E = I.length - 1; _ >= 1 && E >= 0 && w[_] !== I[E]; )
|
|
655
|
+
E--;
|
|
656
|
+
for (; _ >= 1 && E >= 0; _--, E--)
|
|
657
|
+
if (w[_] !== I[E]) {
|
|
658
|
+
if (_ !== 1 || E !== 1)
|
|
659
|
+
do
|
|
660
|
+
if (_--, E--, E < 0 || w[_] !== I[E]) {
|
|
661
|
+
var O = `
|
|
662
|
+
` + w[_].replace(" at new ", " at ");
|
|
663
|
+
return r.displayName && O.includes("<anonymous>") && (O = O.replace("<anonymous>", r.displayName)), typeof r == "function" && Y.set(r, O), O;
|
|
664
|
+
}
|
|
665
|
+
while (_ >= 1 && E >= 0);
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
} finally {
|
|
670
|
+
re = !1, ee.current = C, tt(), Error.prepareStackTrace = k;
|
|
671
|
+
}
|
|
672
|
+
var W = r ? r.displayName || r.name : "", B = W ? Q(W) : "";
|
|
673
|
+
return typeof r == "function" && Y.set(r, B), B;
|
|
674
|
+
}
|
|
675
|
+
function st(r, h, g) {
|
|
676
|
+
return ve(r, !1);
|
|
677
|
+
}
|
|
678
|
+
function nt(r) {
|
|
679
|
+
var h = r.prototype;
|
|
680
|
+
return !!(h && h.isReactComponent);
|
|
681
|
+
}
|
|
682
|
+
function X(r, h, g) {
|
|
683
|
+
if (r == null)
|
|
684
|
+
return "";
|
|
685
|
+
if (typeof r == "function")
|
|
686
|
+
return ve(r, nt(r));
|
|
687
|
+
if (typeof r == "string")
|
|
688
|
+
return Q(r);
|
|
689
|
+
switch (r) {
|
|
690
|
+
case d:
|
|
691
|
+
return Q("Suspense");
|
|
692
|
+
case u:
|
|
693
|
+
return Q("SuspenseList");
|
|
694
|
+
}
|
|
695
|
+
if (typeof r == "object")
|
|
696
|
+
switch (r.$$typeof) {
|
|
697
|
+
case i:
|
|
698
|
+
return st(r.render);
|
|
699
|
+
case x:
|
|
700
|
+
return X(r.type, h, g);
|
|
701
|
+
case f: {
|
|
702
|
+
var v = r, k = v._payload, C = v._init;
|
|
703
|
+
try {
|
|
704
|
+
return X(C(k), h, g);
|
|
705
|
+
} catch {
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return "";
|
|
710
|
+
}
|
|
711
|
+
var V = Object.prototype.hasOwnProperty, we = {}, be = D.ReactDebugCurrentFrame;
|
|
712
|
+
function G(r) {
|
|
713
|
+
if (r) {
|
|
714
|
+
var h = r._owner, g = X(r.type, r._source, h ? h.type : null);
|
|
715
|
+
be.setExtraStackFrame(g);
|
|
716
|
+
} else
|
|
717
|
+
be.setExtraStackFrame(null);
|
|
718
|
+
}
|
|
719
|
+
function ot(r, h, g, v, k) {
|
|
720
|
+
{
|
|
721
|
+
var C = Function.call.bind(V);
|
|
722
|
+
for (var j in r)
|
|
723
|
+
if (C(r, j)) {
|
|
724
|
+
var w = void 0;
|
|
725
|
+
try {
|
|
726
|
+
if (typeof r[j] != "function") {
|
|
727
|
+
var I = Error((v || "React class") + ": " + g + " type `" + j + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof r[j] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
|
|
728
|
+
throw I.name = "Invariant Violation", I;
|
|
729
|
+
}
|
|
730
|
+
w = r[j](h, j, v, g, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
|
|
731
|
+
} catch (_) {
|
|
732
|
+
w = _;
|
|
733
|
+
}
|
|
734
|
+
w && !(w instanceof Error) && (G(k), R("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", v || "React class", g, j, typeof w), G(null)), w instanceof Error && !(w.message in we) && (we[w.message] = !0, G(k), R("Failed %s type: %s", g, w.message), G(null));
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
var at = Array.isArray;
|
|
739
|
+
function se(r) {
|
|
740
|
+
return at(r);
|
|
741
|
+
}
|
|
742
|
+
function it(r) {
|
|
743
|
+
{
|
|
744
|
+
var h = typeof Symbol == "function" && Symbol.toStringTag, g = h && r[Symbol.toStringTag] || r.constructor.name || "Object";
|
|
745
|
+
return g;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function lt(r) {
|
|
749
|
+
try {
|
|
750
|
+
return je(r), !1;
|
|
751
|
+
} catch {
|
|
752
|
+
return !0;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
function je(r) {
|
|
756
|
+
return "" + r;
|
|
757
|
+
}
|
|
758
|
+
function ke(r) {
|
|
759
|
+
if (lt(r))
|
|
760
|
+
return R("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", it(r)), je(r);
|
|
761
|
+
}
|
|
762
|
+
var Ne = D.ReactCurrentOwner, ct = {
|
|
763
|
+
key: !0,
|
|
764
|
+
ref: !0,
|
|
765
|
+
__self: !0,
|
|
766
|
+
__source: !0
|
|
767
|
+
}, Ce, Se;
|
|
768
|
+
function dt(r) {
|
|
769
|
+
if (V.call(r, "ref")) {
|
|
770
|
+
var h = Object.getOwnPropertyDescriptor(r, "ref").get;
|
|
771
|
+
if (h && h.isReactWarning)
|
|
772
|
+
return !1;
|
|
773
|
+
}
|
|
774
|
+
return r.ref !== void 0;
|
|
775
|
+
}
|
|
776
|
+
function ut(r) {
|
|
777
|
+
if (V.call(r, "key")) {
|
|
778
|
+
var h = Object.getOwnPropertyDescriptor(r, "key").get;
|
|
779
|
+
if (h && h.isReactWarning)
|
|
780
|
+
return !1;
|
|
781
|
+
}
|
|
782
|
+
return r.key !== void 0;
|
|
783
|
+
}
|
|
784
|
+
function ht(r, h) {
|
|
785
|
+
typeof r.ref == "string" && Ne.current;
|
|
786
|
+
}
|
|
787
|
+
function ft(r, h) {
|
|
788
|
+
{
|
|
789
|
+
var g = function() {
|
|
790
|
+
Ce || (Ce = !0, R("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", h));
|
|
791
|
+
};
|
|
792
|
+
g.isReactWarning = !0, Object.defineProperty(r, "key", {
|
|
793
|
+
get: g,
|
|
794
|
+
configurable: !0
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
function pt(r, h) {
|
|
799
|
+
{
|
|
800
|
+
var g = function() {
|
|
801
|
+
Se || (Se = !0, R("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", h));
|
|
802
|
+
};
|
|
803
|
+
g.isReactWarning = !0, Object.defineProperty(r, "ref", {
|
|
804
|
+
get: g,
|
|
805
|
+
configurable: !0
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
var xt = function(r, h, g, v, k, C, j) {
|
|
810
|
+
var w = {
|
|
811
|
+
// This tag allows us to uniquely identify this as a React Element
|
|
812
|
+
$$typeof: p,
|
|
813
|
+
// Built-in properties that belong on the element
|
|
814
|
+
type: r,
|
|
815
|
+
key: h,
|
|
816
|
+
ref: g,
|
|
817
|
+
props: j,
|
|
818
|
+
// Record the component responsible for creating this element.
|
|
819
|
+
_owner: C
|
|
820
|
+
};
|
|
821
|
+
return w._store = {}, Object.defineProperty(w._store, "validated", {
|
|
822
|
+
configurable: !1,
|
|
823
|
+
enumerable: !1,
|
|
824
|
+
writable: !0,
|
|
825
|
+
value: !1
|
|
826
|
+
}), Object.defineProperty(w, "_self", {
|
|
827
|
+
configurable: !1,
|
|
828
|
+
enumerable: !1,
|
|
829
|
+
writable: !1,
|
|
830
|
+
value: v
|
|
831
|
+
}), Object.defineProperty(w, "_source", {
|
|
832
|
+
configurable: !1,
|
|
833
|
+
enumerable: !1,
|
|
834
|
+
writable: !1,
|
|
835
|
+
value: k
|
|
836
|
+
}), Object.freeze && (Object.freeze(w.props), Object.freeze(w)), w;
|
|
837
|
+
};
|
|
838
|
+
function gt(r, h, g, v, k) {
|
|
839
|
+
{
|
|
840
|
+
var C, j = {}, w = null, I = null;
|
|
841
|
+
g !== void 0 && (ke(g), w = "" + g), ut(h) && (ke(h.key), w = "" + h.key), dt(h) && (I = h.ref, ht(h, k));
|
|
842
|
+
for (C in h)
|
|
843
|
+
V.call(h, C) && !ct.hasOwnProperty(C) && (j[C] = h[C]);
|
|
844
|
+
if (r && r.defaultProps) {
|
|
845
|
+
var _ = r.defaultProps;
|
|
846
|
+
for (C in _)
|
|
847
|
+
j[C] === void 0 && (j[C] = _[C]);
|
|
848
|
+
}
|
|
849
|
+
if (w || I) {
|
|
850
|
+
var E = typeof r == "function" ? r.displayName || r.name || "Unknown" : r;
|
|
851
|
+
w && ft(j, E), I && pt(j, E);
|
|
852
|
+
}
|
|
853
|
+
return xt(r, w, I, k, v, Ne.current, j);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
var ne = D.ReactCurrentOwner, Te = D.ReactDebugCurrentFrame;
|
|
857
|
+
function L(r) {
|
|
858
|
+
if (r) {
|
|
859
|
+
var h = r._owner, g = X(r.type, r._source, h ? h.type : null);
|
|
860
|
+
Te.setExtraStackFrame(g);
|
|
861
|
+
} else
|
|
862
|
+
Te.setExtraStackFrame(null);
|
|
863
|
+
}
|
|
864
|
+
var oe;
|
|
865
|
+
oe = !1;
|
|
866
|
+
function ae(r) {
|
|
867
|
+
return typeof r == "object" && r !== null && r.$$typeof === p;
|
|
868
|
+
}
|
|
869
|
+
function _e() {
|
|
870
|
+
{
|
|
871
|
+
if (ne.current) {
|
|
872
|
+
var r = $(ne.current.type);
|
|
873
|
+
if (r)
|
|
874
|
+
return `
|
|
875
|
+
|
|
876
|
+
Check the render method of \`` + r + "`.";
|
|
877
|
+
}
|
|
878
|
+
return "";
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
function mt(r) {
|
|
882
|
+
return "";
|
|
883
|
+
}
|
|
884
|
+
var Ee = {};
|
|
885
|
+
function yt(r) {
|
|
886
|
+
{
|
|
887
|
+
var h = _e();
|
|
888
|
+
if (!h) {
|
|
889
|
+
var g = typeof r == "string" ? r : r.displayName || r.name;
|
|
890
|
+
g && (h = `
|
|
891
|
+
|
|
892
|
+
Check the top-level render call using <` + g + ">.");
|
|
893
|
+
}
|
|
894
|
+
return h;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
function Re(r, h) {
|
|
898
|
+
{
|
|
899
|
+
if (!r._store || r._store.validated || r.key != null)
|
|
900
|
+
return;
|
|
901
|
+
r._store.validated = !0;
|
|
902
|
+
var g = yt(h);
|
|
903
|
+
if (Ee[g])
|
|
904
|
+
return;
|
|
905
|
+
Ee[g] = !0;
|
|
906
|
+
var v = "";
|
|
907
|
+
r && r._owner && r._owner !== ne.current && (v = " It was passed a child from " + $(r._owner.type) + "."), L(r), R('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', g, v), L(null);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
function Ie(r, h) {
|
|
911
|
+
{
|
|
912
|
+
if (typeof r != "object")
|
|
913
|
+
return;
|
|
914
|
+
if (se(r))
|
|
915
|
+
for (var g = 0; g < r.length; g++) {
|
|
916
|
+
var v = r[g];
|
|
917
|
+
ae(v) && Re(v, h);
|
|
918
|
+
}
|
|
919
|
+
else if (ae(r))
|
|
920
|
+
r._store && (r._store.validated = !0);
|
|
921
|
+
else if (r) {
|
|
922
|
+
var k = N(r);
|
|
923
|
+
if (typeof k == "function" && k !== r.entries)
|
|
924
|
+
for (var C = k.call(r), j; !(j = C.next()).done; )
|
|
925
|
+
ae(j.value) && Re(j.value, h);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
function vt(r) {
|
|
930
|
+
{
|
|
931
|
+
var h = r.type;
|
|
932
|
+
if (h == null || typeof h == "string")
|
|
933
|
+
return;
|
|
934
|
+
var g;
|
|
935
|
+
if (typeof h == "function")
|
|
936
|
+
g = h.propTypes;
|
|
937
|
+
else if (typeof h == "object" && (h.$$typeof === i || // Note: Memo only checks outer props here.
|
|
938
|
+
// Inner props are checked in the reconciler.
|
|
939
|
+
h.$$typeof === x))
|
|
940
|
+
g = h.propTypes;
|
|
941
|
+
else
|
|
942
|
+
return;
|
|
943
|
+
if (g) {
|
|
944
|
+
var v = $(h);
|
|
945
|
+
ot(g, r.props, "prop", v, r);
|
|
946
|
+
} else if (h.PropTypes !== void 0 && !oe) {
|
|
947
|
+
oe = !0;
|
|
948
|
+
var k = $(h);
|
|
949
|
+
R("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", k || "Unknown");
|
|
950
|
+
}
|
|
951
|
+
typeof h.getDefaultProps == "function" && !h.getDefaultProps.isReactClassApproved && R("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
function wt(r) {
|
|
955
|
+
{
|
|
956
|
+
for (var h = Object.keys(r.props), g = 0; g < h.length; g++) {
|
|
957
|
+
var v = h[g];
|
|
958
|
+
if (v !== "children" && v !== "key") {
|
|
959
|
+
L(r), R("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", v), L(null);
|
|
960
|
+
break;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
r.ref !== null && (L(r), R("Invalid attribute `ref` supplied to `React.Fragment`."), L(null));
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
var Ae = {};
|
|
967
|
+
function Oe(r, h, g, v, k, C) {
|
|
968
|
+
{
|
|
969
|
+
var j = He(r);
|
|
970
|
+
if (!j) {
|
|
971
|
+
var w = "";
|
|
972
|
+
(r === void 0 || typeof r == "object" && r !== null && Object.keys(r).length === 0) && (w += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");
|
|
973
|
+
var I = mt();
|
|
974
|
+
I ? w += I : w += _e();
|
|
975
|
+
var _;
|
|
976
|
+
r === null ? _ = "null" : se(r) ? _ = "array" : r !== void 0 && r.$$typeof === p ? (_ = "<" + ($(r.type) || "Unknown") + " />", w = " Did you accidentally export a JSX literal instead of a component?") : _ = typeof r, R("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", _, w);
|
|
977
|
+
}
|
|
978
|
+
var E = gt(r, h, g, k, C);
|
|
979
|
+
if (E == null)
|
|
980
|
+
return E;
|
|
981
|
+
if (j) {
|
|
982
|
+
var O = h.children;
|
|
983
|
+
if (O !== void 0)
|
|
984
|
+
if (v)
|
|
985
|
+
if (se(O)) {
|
|
986
|
+
for (var W = 0; W < O.length; W++)
|
|
987
|
+
Ie(O[W], r);
|
|
988
|
+
Object.freeze && Object.freeze(O);
|
|
989
|
+
} else
|
|
990
|
+
R("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
|
|
991
|
+
else
|
|
992
|
+
Ie(O, r);
|
|
993
|
+
}
|
|
994
|
+
if (V.call(h, "key")) {
|
|
995
|
+
var B = $(r), A = Object.keys(h).filter(function(St) {
|
|
996
|
+
return St !== "key";
|
|
997
|
+
}), ie = A.length > 0 ? "{key: someKey, " + A.join(": ..., ") + ": ...}" : "{key: someKey}";
|
|
998
|
+
if (!Ae[B + ie]) {
|
|
999
|
+
var Ct = A.length > 0 ? "{" + A.join(": ..., ") + ": ...}" : "{}";
|
|
1000
|
+
R(`A props object containing a "key" prop is being spread into JSX:
|
|
1001
|
+
let props = %s;
|
|
1002
|
+
<%s {...props} />
|
|
1003
|
+
React keys must be passed directly to JSX without using spread:
|
|
1004
|
+
let props = %s;
|
|
1005
|
+
<%s key={someKey} {...props} />`, ie, B, Ct, B), Ae[B + ie] = !0;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
return r === e ? wt(E) : vt(E), E;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
function bt(r, h, g) {
|
|
1012
|
+
return Oe(r, h, g, !0);
|
|
1013
|
+
}
|
|
1014
|
+
function jt(r, h, g) {
|
|
1015
|
+
return Oe(r, h, g, !1);
|
|
1016
|
+
}
|
|
1017
|
+
var kt = jt, Nt = bt;
|
|
1018
|
+
q.Fragment = e, q.jsx = kt, q.jsxs = Nt;
|
|
1019
|
+
})()), q;
|
|
1020
|
+
}
|
|
1021
|
+
var Pe;
|
|
1022
|
+
function Ot() {
|
|
1023
|
+
return Pe || (Pe = 1, process.env.NODE_ENV === "production" ? H.exports = It() : H.exports = At()), H.exports;
|
|
1024
|
+
}
|
|
1025
|
+
var t = Ot();
|
|
1026
|
+
const Dt = ({ block: c }) => /* @__PURE__ */ t.jsx("div", { className: "text-block", children: /* @__PURE__ */ t.jsx("p", { className: "whitespace-pre-wrap", children: c.content }) }), $t = ({ block: c }) => /* @__PURE__ */ t.jsx("div", { className: "markdown-block prose prose-sm max-w-none", children: /* @__PURE__ */ t.jsx(U, { remarkPlugins: [z], children: c.content }) }), Pt = ({
|
|
1027
|
+
isOpen: c,
|
|
1028
|
+
onClose: p,
|
|
1029
|
+
toolName: l,
|
|
1030
|
+
toolTitle: e,
|
|
1031
|
+
toolIcon: s,
|
|
1032
|
+
input: n,
|
|
1033
|
+
output: o
|
|
1034
|
+
}) => {
|
|
1035
|
+
F(() => {
|
|
1036
|
+
const f = (m) => {
|
|
1037
|
+
m.key === "Escape" && c && p();
|
|
1038
|
+
};
|
|
1039
|
+
return window.addEventListener("keydown", f), () => window.removeEventListener("keydown", f);
|
|
1040
|
+
}, [c, p]), F(() => (c ? document.body.style.overflow = "hidden" : document.body.style.overflow = "", () => {
|
|
1041
|
+
document.body.style.overflow = "";
|
|
1042
|
+
}), [c]);
|
|
1043
|
+
const a = () => s ? typeof s == "string" ? /* @__PURE__ */ t.jsx(
|
|
1044
|
+
"img",
|
|
1045
|
+
{
|
|
1046
|
+
src: s,
|
|
1047
|
+
alt: l,
|
|
1048
|
+
className: "w-5 h-5",
|
|
1049
|
+
onError: (f) => {
|
|
1050
|
+
f.currentTarget.style.display = "none";
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
) : /* @__PURE__ */ t.jsx("div", { className: "w-5 h-5", children: s }) : null, i = (f) => {
|
|
1054
|
+
if (f == null)
|
|
1055
|
+
return "";
|
|
1056
|
+
if (typeof f == "string")
|
|
1057
|
+
return f;
|
|
1058
|
+
try {
|
|
1059
|
+
return JSON.stringify(f, null, 2);
|
|
1060
|
+
} catch {
|
|
1061
|
+
return String(f);
|
|
1062
|
+
}
|
|
1063
|
+
}, d = () => l === "execute_code", u = (f) => {
|
|
1064
|
+
const m = `\`\`\`python
|
|
1065
|
+
${f}
|
|
1066
|
+
\`\`\``;
|
|
1067
|
+
return /* @__PURE__ */ t.jsx("div", { className: "markdown-block prose prose-sm max-w-none", children: /* @__PURE__ */ t.jsx(U, { remarkPlugins: [z], children: m }) });
|
|
1068
|
+
}, x = (f) => /* @__PURE__ */ t.jsx("div", { className: "markdown-block prose prose-sm max-w-none", children: /* @__PURE__ */ t.jsx(U, { remarkPlugins: [z], children: f }) });
|
|
1069
|
+
return c ? /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1070
|
+
/* @__PURE__ */ t.jsx(
|
|
1071
|
+
"div",
|
|
1072
|
+
{
|
|
1073
|
+
className: "fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity",
|
|
1074
|
+
onClick: p
|
|
1075
|
+
}
|
|
1076
|
+
),
|
|
1077
|
+
/* @__PURE__ */ t.jsxs("div", { className: "fixed right-0 top-0 bottom-0 w-[600px] max-w-[90vw] bg-white shadow-xl z-50 flex flex-col animate-slide-in-right", children: [
|
|
1078
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200", children: [
|
|
1079
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1080
|
+
a(),
|
|
1081
|
+
/* @__PURE__ */ t.jsx("h2", { className: "text-lg font-semibold text-gray-900", children: e })
|
|
1082
|
+
] }),
|
|
1083
|
+
/* @__PURE__ */ t.jsx(
|
|
1084
|
+
"button",
|
|
1085
|
+
{
|
|
1086
|
+
onClick: p,
|
|
1087
|
+
className: "w-8 h-8 flex items-center justify-center rounded-full hover:bg-gray-100 transition-colors",
|
|
1088
|
+
"aria-label": "关闭",
|
|
1089
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1090
|
+
"svg",
|
|
1091
|
+
{
|
|
1092
|
+
className: "w-5 h-5 text-gray-500",
|
|
1093
|
+
viewBox: "0 0 24 24",
|
|
1094
|
+
fill: "none",
|
|
1095
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1096
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1097
|
+
"path",
|
|
1098
|
+
{
|
|
1099
|
+
d: "M18 6L6 18M6 6L18 18",
|
|
1100
|
+
stroke: "currentColor",
|
|
1101
|
+
strokeWidth: "2",
|
|
1102
|
+
strokeLinecap: "round",
|
|
1103
|
+
strokeLinejoin: "round"
|
|
1104
|
+
}
|
|
1105
|
+
)
|
|
1106
|
+
}
|
|
1107
|
+
)
|
|
1108
|
+
}
|
|
1109
|
+
)
|
|
1110
|
+
] }),
|
|
1111
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: [
|
|
1112
|
+
d() ? /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1113
|
+
n != null && /* @__PURE__ */ t.jsxs("div", { className: "mb-6", children: [
|
|
1114
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输入" }),
|
|
1115
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-x-auto", children: u(typeof n == "string" ? n : i(n)) })
|
|
1116
|
+
] }),
|
|
1117
|
+
o != null && /* @__PURE__ */ t.jsxs("div", { children: [
|
|
1118
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输出" }),
|
|
1119
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-x-auto", children: x(typeof o == "string" ? o : i(o)) })
|
|
1120
|
+
] })
|
|
1121
|
+
] }) : /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1122
|
+
n != null && /* @__PURE__ */ t.jsxs("div", { className: "mb-6", children: [
|
|
1123
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输入" }),
|
|
1124
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4", children: /* @__PURE__ */ t.jsx("pre", { className: "text-sm text-gray-700 whitespace-pre-wrap break-words font-mono", children: i(n) }) })
|
|
1125
|
+
] }),
|
|
1126
|
+
o != null && /* @__PURE__ */ t.jsxs("div", { children: [
|
|
1127
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输出" }),
|
|
1128
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4", children: /* @__PURE__ */ t.jsx("pre", { className: "text-sm text-gray-700 whitespace-pre-wrap break-words font-mono", children: i(o) }) })
|
|
1129
|
+
] })
|
|
1130
|
+
] }),
|
|
1131
|
+
n == null && o == null && /* @__PURE__ */ t.jsx("div", { className: "text-center text-gray-400 py-8", children: "暂无数据" })
|
|
1132
|
+
] })
|
|
1133
|
+
] }),
|
|
1134
|
+
/* @__PURE__ */ t.jsx("style", { children: `
|
|
1135
|
+
@keyframes slide-in-right {
|
|
1136
|
+
from {
|
|
1137
|
+
transform: translateX(100%);
|
|
1138
|
+
}
|
|
1139
|
+
to {
|
|
1140
|
+
transform: translateX(0);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
.animate-slide-in-right {
|
|
1144
|
+
animation: slide-in-right 0.3s ease-out;
|
|
1145
|
+
}
|
|
1146
|
+
` })
|
|
1147
|
+
] }) : null;
|
|
1148
|
+
}, We = ({ block: c }) => {
|
|
1149
|
+
const [p, l] = Be(!1), { icon: e, title: s, name: n, input: o, output: a } = c.content, i = () => e ? typeof e == "string" ? /* @__PURE__ */ t.jsx(
|
|
1150
|
+
"img",
|
|
1151
|
+
{
|
|
1152
|
+
src: e,
|
|
1153
|
+
alt: n,
|
|
1154
|
+
className: "w-5 h-5 flex-shrink-0",
|
|
1155
|
+
onError: (d) => {
|
|
1156
|
+
d.currentTarget.style.display = "none";
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
) : /* @__PURE__ */ t.jsx("div", { className: "w-5 h-5 flex-shrink-0", children: e }) : null;
|
|
1160
|
+
return /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1161
|
+
/* @__PURE__ */ t.jsx("div", { className: "tool-block bg-white border border-[#d9d9d9] rounded-[6px] my-2", children: /* @__PURE__ */ t.jsxs(
|
|
1162
|
+
"div",
|
|
1163
|
+
{
|
|
1164
|
+
className: "flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-gray-50 transition-colors",
|
|
1165
|
+
onClick: () => l(!0),
|
|
1166
|
+
children: [
|
|
1167
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
1168
|
+
i(),
|
|
1169
|
+
/* @__PURE__ */ t.jsx("span", { className: "text-sm text-[rgba(0,0,0,0.65)] truncate", children: s })
|
|
1170
|
+
] }),
|
|
1171
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex items-center justify-center w-4 h-4 flex-shrink-0", children: /* @__PURE__ */ t.jsx(
|
|
1172
|
+
"svg",
|
|
1173
|
+
{
|
|
1174
|
+
className: "w-4 h-4 text-gray-400",
|
|
1175
|
+
viewBox: "0 0 24 24",
|
|
1176
|
+
fill: "none",
|
|
1177
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1178
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1179
|
+
"path",
|
|
1180
|
+
{
|
|
1181
|
+
d: "M9 18L15 12L9 6",
|
|
1182
|
+
stroke: "currentColor",
|
|
1183
|
+
strokeWidth: "2",
|
|
1184
|
+
strokeLinecap: "round",
|
|
1185
|
+
strokeLinejoin: "round"
|
|
1186
|
+
}
|
|
1187
|
+
)
|
|
1188
|
+
}
|
|
1189
|
+
) })
|
|
1190
|
+
]
|
|
1191
|
+
}
|
|
1192
|
+
) }),
|
|
1193
|
+
/* @__PURE__ */ t.jsx(
|
|
1194
|
+
Pt,
|
|
1195
|
+
{
|
|
1196
|
+
isOpen: p,
|
|
1197
|
+
onClose: () => l(!1),
|
|
1198
|
+
toolName: n,
|
|
1199
|
+
toolTitle: s,
|
|
1200
|
+
toolIcon: e,
|
|
1201
|
+
input: o,
|
|
1202
|
+
output: a
|
|
1203
|
+
}
|
|
1204
|
+
)
|
|
1205
|
+
] });
|
|
1206
|
+
}, Mt = ({ block: c }) => {
|
|
1207
|
+
const { input: p, results: l } = c.content, e = {
|
|
1208
|
+
type: T.TOOL,
|
|
1209
|
+
content: {
|
|
1210
|
+
name: "web_search",
|
|
1211
|
+
title: `联网搜索:${p}`,
|
|
1212
|
+
icon: /* @__PURE__ */ t.jsx(
|
|
1213
|
+
"svg",
|
|
1214
|
+
{
|
|
1215
|
+
className: "w-5 h-5 text-blue-600",
|
|
1216
|
+
fill: "none",
|
|
1217
|
+
stroke: "currentColor",
|
|
1218
|
+
viewBox: "0 0 24 24",
|
|
1219
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1220
|
+
"path",
|
|
1221
|
+
{
|
|
1222
|
+
strokeLinecap: "round",
|
|
1223
|
+
strokeLinejoin: "round",
|
|
1224
|
+
strokeWidth: 2,
|
|
1225
|
+
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
1226
|
+
}
|
|
1227
|
+
)
|
|
1228
|
+
}
|
|
1229
|
+
),
|
|
1230
|
+
input: {
|
|
1231
|
+
query: p
|
|
1232
|
+
},
|
|
1233
|
+
output: {
|
|
1234
|
+
results: l.map((s) => ({
|
|
1235
|
+
title: s.title,
|
|
1236
|
+
content: s.content,
|
|
1237
|
+
link: s.link,
|
|
1238
|
+
media: s.media,
|
|
1239
|
+
icon: s.icon
|
|
1240
|
+
})),
|
|
1241
|
+
total: l.length
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
return /* @__PURE__ */ t.jsx(We, { block: e });
|
|
1246
|
+
}, Bt = ({ message: c }) => {
|
|
1247
|
+
const p = c.role.type === P.USER, l = () => Array.isArray(c.content) ? /* @__PURE__ */ t.jsx("div", { className: "space-y-2", children: c.content.map((e, s) => {
|
|
1248
|
+
switch (e.type) {
|
|
1249
|
+
case T.TEXT:
|
|
1250
|
+
return /* @__PURE__ */ t.jsx(Dt, { block: e }, s);
|
|
1251
|
+
case T.MARKDOWN:
|
|
1252
|
+
return /* @__PURE__ */ t.jsx($t, { block: e }, s);
|
|
1253
|
+
case T.WEB_SEARCH:
|
|
1254
|
+
return /* @__PURE__ */ t.jsx(Mt, { block: e }, s);
|
|
1255
|
+
case T.TOOL:
|
|
1256
|
+
return /* @__PURE__ */ t.jsx(We, { block: e }, s);
|
|
1257
|
+
default:
|
|
1258
|
+
return null;
|
|
1259
|
+
}
|
|
1260
|
+
}) }) : /* @__PURE__ */ t.jsx("p", { className: "text-[14px] whitespace-pre-wrap break-words leading-[24px]", children: c.content });
|
|
1261
|
+
return /* @__PURE__ */ t.jsxs("div", { className: `flex ${p ? "justify-end" : "justify-start"} mb-4`, children: [
|
|
1262
|
+
!p && /* @__PURE__ */ t.jsx("div", { className: "w-[21px] h-[21px] mr-2 flex-shrink-0 mt-1", children: /* @__PURE__ */ t.jsx("img", { src: "/icons/assistant.svg", alt: "AI Assistant", className: "w-[21px] h-[21px]" }) }),
|
|
1263
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex flex-col gap-2 max-w-[calc(100%-40px)]", children: [
|
|
1264
|
+
p && c.applicationContext && c.applicationContext.title && /* @__PURE__ */ t.jsx("div", { className: "self-end", children: /* @__PURE__ */ t.jsx("span", { className: "inline-block bg-[rgba(18,110,227,0.04)] rounded-[8px] px-[14px] py-[5px] text-[12px] leading-[24px] text-[rgba(0,0,0,0.85)]", style: { fontFamily: "Noto Sans SC" }, children: c.applicationContext.title }) }),
|
|
1265
|
+
/* @__PURE__ */ t.jsx(
|
|
1266
|
+
"div",
|
|
1267
|
+
{
|
|
1268
|
+
className: `rounded-[8px] ${p ? "bg-[rgba(18,110,227,0.1)] text-[rgba(0,0,0,0.85)] px-[14px] py-[5px]" : "bg-white text-black px-4 py-3"}`,
|
|
1269
|
+
style: { fontFamily: "Noto Sans SC" },
|
|
1270
|
+
children: l()
|
|
1271
|
+
}
|
|
1272
|
+
)
|
|
1273
|
+
] })
|
|
1274
|
+
] });
|
|
1275
|
+
}, Fe = ({ messages: c }) => {
|
|
1276
|
+
const p = Le(null), l = () => {
|
|
1277
|
+
var e;
|
|
1278
|
+
(e = p.current) == null || e.scrollIntoView({ behavior: "smooth" });
|
|
1279
|
+
};
|
|
1280
|
+
return F(() => {
|
|
1281
|
+
l();
|
|
1282
|
+
}, [c]), /* @__PURE__ */ t.jsxs("div", { className: "px-5 py-3", children: [
|
|
1283
|
+
c.map((e) => /* @__PURE__ */ t.jsx(Bt, { message: e }, e.messageId)),
|
|
1284
|
+
/* @__PURE__ */ t.jsx("div", { ref: p })
|
|
1285
|
+
] });
|
|
1286
|
+
}, Ue = ({
|
|
1287
|
+
value: c,
|
|
1288
|
+
onChange: p,
|
|
1289
|
+
onSend: l,
|
|
1290
|
+
context: e,
|
|
1291
|
+
onRemoveContext: s,
|
|
1292
|
+
disabled: n = !1,
|
|
1293
|
+
isStreaming: o = !1,
|
|
1294
|
+
onStop: a
|
|
1295
|
+
}) => {
|
|
1296
|
+
const i = (d) => {
|
|
1297
|
+
d.key === "Enter" && !d.shiftKey && (d.preventDefault(), l());
|
|
1298
|
+
};
|
|
1299
|
+
return /* @__PURE__ */ t.jsx("div", { className: "px-5 pb-3 bg-white", children: /* @__PURE__ */ t.jsxs("div", { className: "relative h-40", children: [
|
|
1300
|
+
e && e.title && /* @__PURE__ */ t.jsxs("div", { className: "absolute top-0 left-1 right-1 bg-[rgba(18,110,227,0.04)] rounded-lg px-4 py-2 h-10 flex items-center", children: [
|
|
1301
|
+
/* @__PURE__ */ t.jsx("p", { className: "text-[12px] leading-6 text-[rgba(0,0,0,0.85)] truncate", style: { fontFamily: "Noto Sans SC" }, children: e.title }),
|
|
1302
|
+
/* @__PURE__ */ t.jsx(
|
|
1303
|
+
"button",
|
|
1304
|
+
{
|
|
1305
|
+
onClick: s,
|
|
1306
|
+
className: "ml-auto text-[rgba(0,0,0,0.45)] hover:text-[rgba(0,0,0,0.85)] transition-colors flex-shrink-0",
|
|
1307
|
+
title: "移除上下文",
|
|
1308
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1309
|
+
"svg",
|
|
1310
|
+
{
|
|
1311
|
+
className: "w-3 h-3",
|
|
1312
|
+
fill: "none",
|
|
1313
|
+
stroke: "currentColor",
|
|
1314
|
+
viewBox: "0 0 24 24",
|
|
1315
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1316
|
+
"path",
|
|
1317
|
+
{
|
|
1318
|
+
strokeLinecap: "round",
|
|
1319
|
+
strokeLinejoin: "round",
|
|
1320
|
+
strokeWidth: 2,
|
|
1321
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
1322
|
+
}
|
|
1323
|
+
)
|
|
1324
|
+
}
|
|
1325
|
+
)
|
|
1326
|
+
}
|
|
1327
|
+
)
|
|
1328
|
+
] }),
|
|
1329
|
+
/* @__PURE__ */ t.jsxs(
|
|
1330
|
+
"div",
|
|
1331
|
+
{
|
|
1332
|
+
className: "absolute bg-white border-[1.5px] border-solid border-[#3b9be0] rounded-2xl overflow-hidden",
|
|
1333
|
+
style: {
|
|
1334
|
+
top: e && e.title ? "48px" : "0",
|
|
1335
|
+
left: 0,
|
|
1336
|
+
right: 0,
|
|
1337
|
+
bottom: 0
|
|
1338
|
+
},
|
|
1339
|
+
children: [
|
|
1340
|
+
/* @__PURE__ */ t.jsx(
|
|
1341
|
+
"textarea",
|
|
1342
|
+
{
|
|
1343
|
+
value: c,
|
|
1344
|
+
onChange: (d) => p(d.target.value),
|
|
1345
|
+
onKeyDown: i,
|
|
1346
|
+
placeholder: "查询任何问题",
|
|
1347
|
+
disabled: n,
|
|
1348
|
+
className: "w-full h-full resize-none px-3 py-3 text-[14px] leading-normal text-black placeholder:text-[rgba(0,0,0,0.25)] focus:outline-none disabled:bg-gray-50 disabled:cursor-not-allowed",
|
|
1349
|
+
style: { fontFamily: "Noto Sans, Noto Sans SC, Noto Sans JP, sans-serif" },
|
|
1350
|
+
maxLength: 4e3
|
|
1351
|
+
}
|
|
1352
|
+
),
|
|
1353
|
+
o ? (
|
|
1354
|
+
// 停止按钮:在接收 AI 流式响应时显示
|
|
1355
|
+
/* @__PURE__ */ t.jsx(
|
|
1356
|
+
"button",
|
|
1357
|
+
{
|
|
1358
|
+
onClick: a,
|
|
1359
|
+
className: "absolute bottom-3 right-3 w-8 h-8 flex items-center justify-center bg-red-500 hover:bg-red-600 rounded transition-colors",
|
|
1360
|
+
title: "停止响应",
|
|
1361
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1362
|
+
"svg",
|
|
1363
|
+
{
|
|
1364
|
+
className: "w-4 h-4 text-white",
|
|
1365
|
+
fill: "currentColor",
|
|
1366
|
+
viewBox: "0 0 24 24",
|
|
1367
|
+
children: /* @__PURE__ */ t.jsx("rect", { x: "6", y: "6", width: "12", height: "12" })
|
|
1368
|
+
}
|
|
1369
|
+
)
|
|
1370
|
+
}
|
|
1371
|
+
)
|
|
1372
|
+
) : (
|
|
1373
|
+
// 发送按钮:正常状态下显示
|
|
1374
|
+
/* @__PURE__ */ t.jsx(
|
|
1375
|
+
"button",
|
|
1376
|
+
{
|
|
1377
|
+
onClick: l,
|
|
1378
|
+
disabled: n || !c.trim(),
|
|
1379
|
+
className: "absolute bottom-3 right-3 w-8 h-8 flex items-center justify-center disabled:opacity-30 disabled:cursor-not-allowed transition-opacity",
|
|
1380
|
+
title: n ? "正在发送..." : "发送消息",
|
|
1381
|
+
children: /* @__PURE__ */ t.jsx("img", { src: "/icons/send.svg", alt: "发送", className: "w-8 h-8" })
|
|
1382
|
+
}
|
|
1383
|
+
)
|
|
1384
|
+
)
|
|
1385
|
+
]
|
|
1386
|
+
}
|
|
1387
|
+
)
|
|
1388
|
+
] }) });
|
|
1389
|
+
}, ze = ({
|
|
1390
|
+
title: c = "Copilot",
|
|
1391
|
+
onClose: p,
|
|
1392
|
+
onNewChat: l,
|
|
1393
|
+
onExpand: e,
|
|
1394
|
+
onMore: s
|
|
1395
|
+
}) => /* @__PURE__ */ t.jsx("div", { className: "relative h-14 w-full bg-white", children: /* @__PURE__ */ t.jsxs("div", { className: "absolute left-[23px] top-3 h-8 w-[440px]", children: [
|
|
1396
|
+
/* @__PURE__ */ t.jsxs("div", { className: "absolute left-0 top-0 flex items-center h-8", children: [
|
|
1397
|
+
/* @__PURE__ */ t.jsx("div", { className: "w-8 h-8", children: /* @__PURE__ */ t.jsx("img", { src: "/icons/assistant.svg", alt: "Copilot", className: "w-8 h-8" }) }),
|
|
1398
|
+
/* @__PURE__ */ t.jsx("div", { className: "absolute left-[40px] top-1/2 -translate-y-1/2", children: /* @__PURE__ */ t.jsx("p", { className: "font-medium text-[18px] leading-4 text-black whitespace-nowrap", style: { fontFamily: "Noto Sans SC" }, children: c }) })
|
|
1399
|
+
] }),
|
|
1400
|
+
/* @__PURE__ */ t.jsxs("div", { className: "absolute right-0 top-0 h-8 flex items-center", children: [
|
|
1401
|
+
s && /* @__PURE__ */ t.jsx(
|
|
1402
|
+
"button",
|
|
1403
|
+
{
|
|
1404
|
+
onClick: s,
|
|
1405
|
+
className: "w-5 h-5 flex items-center justify-center hover:opacity-70 transition-opacity",
|
|
1406
|
+
title: "更多选项",
|
|
1407
|
+
children: /* @__PURE__ */ t.jsx("img", { src: "/icons/more.svg", alt: "更多", className: "w-5 h-5" })
|
|
1408
|
+
}
|
|
1409
|
+
),
|
|
1410
|
+
l && /* @__PURE__ */ t.jsx(
|
|
1411
|
+
"button",
|
|
1412
|
+
{
|
|
1413
|
+
onClick: l,
|
|
1414
|
+
className: "ml-2 w-[14px] h-[14px] flex items-center justify-center hover:opacity-70 transition-opacity",
|
|
1415
|
+
title: "新建会话",
|
|
1416
|
+
children: /* @__PURE__ */ t.jsx("img", { src: "/icons/new.svg", alt: "新建会话", className: "w-[14px] h-[14px]" })
|
|
1417
|
+
}
|
|
1418
|
+
),
|
|
1419
|
+
e && /* @__PURE__ */ t.jsx(
|
|
1420
|
+
"button",
|
|
1421
|
+
{
|
|
1422
|
+
onClick: e,
|
|
1423
|
+
className: "ml-2 w-[14px] h-[13px] flex items-center justify-center hover:opacity-70 transition-opacity",
|
|
1424
|
+
title: "展开",
|
|
1425
|
+
children: /* @__PURE__ */ t.jsx("img", { src: "/icons/expand.svg", alt: "展开", className: "w-[14px] h-[13px]" })
|
|
1426
|
+
}
|
|
1427
|
+
),
|
|
1428
|
+
p && /* @__PURE__ */ t.jsx(
|
|
1429
|
+
"button",
|
|
1430
|
+
{
|
|
1431
|
+
onClick: p,
|
|
1432
|
+
className: "ml-2 w-4 h-4 flex items-center justify-center hover:opacity-70 transition-opacity",
|
|
1433
|
+
title: "关闭",
|
|
1434
|
+
children: /* @__PURE__ */ t.jsx("img", { src: "/icons/close.svg", alt: "关闭", className: "w-4 h-4" })
|
|
1435
|
+
}
|
|
1436
|
+
)
|
|
1437
|
+
] })
|
|
1438
|
+
] }) }), Je = ({
|
|
1439
|
+
onQuestionClick: c,
|
|
1440
|
+
prologue: p,
|
|
1441
|
+
predefinedQuestions: l
|
|
1442
|
+
}) => {
|
|
1443
|
+
const e = "你好!我是 Copilot,你的智能浏览助手。我可以帮你理解和分析当前页面的内容。", s = [
|
|
1444
|
+
"🔍 我现在有哪些需要优先处理的高风险工单?",
|
|
1445
|
+
"🛠️ 处理 [问题类型] 工单有什么推荐方案?",
|
|
1446
|
+
"💡 如何避免处理 [技术领域] 问题的常见错误?"
|
|
1447
|
+
], n = p || e, o = l && l.length > 0 ? l : s, a = (i) => {
|
|
1448
|
+
c && c(i);
|
|
1449
|
+
};
|
|
1450
|
+
return /* @__PURE__ */ t.jsxs("div", { className: "flex flex-col gap-4 px-6 pt-28 pb-4", children: [
|
|
1451
|
+
/* @__PURE__ */ t.jsx(
|
|
1452
|
+
"p",
|
|
1453
|
+
{
|
|
1454
|
+
className: "text-[14px] leading-[17px] text-[rgba(0,0,0,0.65)]",
|
|
1455
|
+
style: { fontFamily: "Noto Sans SC" },
|
|
1456
|
+
children: n
|
|
1457
|
+
}
|
|
1458
|
+
),
|
|
1459
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex flex-col gap-3", children: o.map((i, d) => /* @__PURE__ */ t.jsx(
|
|
1460
|
+
"button",
|
|
1461
|
+
{
|
|
1462
|
+
onClick: () => a(i),
|
|
1463
|
+
className: "w-full bg-white border border-[rgba(0,0,0,0.1)] rounded-[6px] px-3 py-2 text-left text-[14px] leading-6 text-black hover:border-[#3b9be0] hover:bg-[rgba(18,110,227,0.04)] transition-all",
|
|
1464
|
+
style: { fontFamily: "Noto Sans SC" },
|
|
1465
|
+
children: i
|
|
1466
|
+
},
|
|
1467
|
+
d
|
|
1468
|
+
)) })
|
|
1469
|
+
] });
|
|
1470
|
+
};
|
|
1471
|
+
class Lt extends le {
|
|
1472
|
+
/**
|
|
1473
|
+
* 实现 React.Component.render() 方法
|
|
1474
|
+
* 渲染 Copilot 模式的界面
|
|
1475
|
+
*/
|
|
1476
|
+
render() {
|
|
1477
|
+
if (!this.props.visible)
|
|
1478
|
+
return null;
|
|
1479
|
+
const { title: p = "Copilot", onClose: l } = this.props, { messages: e, textInput: s, applicationContext: n, isSending: o, onboardingInfo: a, isLoadingOnboarding: i, streamingMessageId: d } = this.state, u = e.length === 0, x = d !== null;
|
|
1480
|
+
return /* @__PURE__ */ t.jsxs("div", { className: "flex flex-col h-full w-full bg-white shadow-2xl", children: [
|
|
1481
|
+
/* @__PURE__ */ t.jsx(
|
|
1482
|
+
ze,
|
|
1483
|
+
{
|
|
1484
|
+
title: p,
|
|
1485
|
+
onClose: l,
|
|
1486
|
+
onNewChat: this.createConversation
|
|
1487
|
+
}
|
|
1488
|
+
),
|
|
1489
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex-1 overflow-y-auto", children: u ? i ? (
|
|
1490
|
+
// 加载中,显示加载提示
|
|
1491
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ t.jsxs("div", { className: "text-center", children: [
|
|
1492
|
+
/* @__PURE__ */ t.jsx("div", { className: "inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mb-4" }),
|
|
1493
|
+
/* @__PURE__ */ t.jsx("p", { className: "text-sm text-gray-500", children: "正在加载..." })
|
|
1494
|
+
] }) })
|
|
1495
|
+
) : (
|
|
1496
|
+
// 加载完成,显示开场白
|
|
1497
|
+
/* @__PURE__ */ t.jsx(
|
|
1498
|
+
Je,
|
|
1499
|
+
{
|
|
1500
|
+
onQuestionClick: this.handleQuestionClick,
|
|
1501
|
+
prologue: a == null ? void 0 : a.prologue,
|
|
1502
|
+
predefinedQuestions: a == null ? void 0 : a.predefinedQuestions
|
|
1503
|
+
}
|
|
1504
|
+
)
|
|
1505
|
+
) : /* @__PURE__ */ t.jsx(Fe, { messages: e }) }),
|
|
1506
|
+
/* @__PURE__ */ t.jsx(
|
|
1507
|
+
Ue,
|
|
1508
|
+
{
|
|
1509
|
+
value: s,
|
|
1510
|
+
onChange: this.setTextInput,
|
|
1511
|
+
onSend: this.handleSend,
|
|
1512
|
+
context: n,
|
|
1513
|
+
onRemoveContext: this.removeApplicationContext,
|
|
1514
|
+
disabled: o,
|
|
1515
|
+
isStreaming: x,
|
|
1516
|
+
onStop: this.handleStop
|
|
1517
|
+
}
|
|
1518
|
+
)
|
|
1519
|
+
] });
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
const Wt = ({ block: c }) => /* @__PURE__ */ t.jsx("div", { className: "text-block", children: /* @__PURE__ */ t.jsx("p", { className: "whitespace-pre-wrap", children: c.content }) }), Ft = ({ block: c }) => /* @__PURE__ */ t.jsx("div", { className: "markdown-block prose prose-sm max-w-none", children: /* @__PURE__ */ t.jsx(U, { remarkPlugins: [z], children: c.content }) }), Ut = ({
|
|
1523
|
+
isOpen: c,
|
|
1524
|
+
onClose: p,
|
|
1525
|
+
toolName: l,
|
|
1526
|
+
toolTitle: e,
|
|
1527
|
+
toolIcon: s,
|
|
1528
|
+
input: n,
|
|
1529
|
+
output: o
|
|
1530
|
+
}) => {
|
|
1531
|
+
F(() => {
|
|
1532
|
+
const f = (m) => {
|
|
1533
|
+
m.key === "Escape" && c && p();
|
|
1534
|
+
};
|
|
1535
|
+
return window.addEventListener("keydown", f), () => window.removeEventListener("keydown", f);
|
|
1536
|
+
}, [c, p]), F(() => (c ? document.body.style.overflow = "hidden" : document.body.style.overflow = "", () => {
|
|
1537
|
+
document.body.style.overflow = "";
|
|
1538
|
+
}), [c]);
|
|
1539
|
+
const a = () => s ? typeof s == "string" ? /* @__PURE__ */ t.jsx(
|
|
1540
|
+
"img",
|
|
1541
|
+
{
|
|
1542
|
+
src: s,
|
|
1543
|
+
alt: l,
|
|
1544
|
+
className: "w-5 h-5",
|
|
1545
|
+
onError: (f) => {
|
|
1546
|
+
f.currentTarget.style.display = "none";
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
) : /* @__PURE__ */ t.jsx("div", { className: "w-5 h-5", children: s }) : null, i = (f) => {
|
|
1550
|
+
if (f == null)
|
|
1551
|
+
return "";
|
|
1552
|
+
if (typeof f == "string")
|
|
1553
|
+
return f;
|
|
1554
|
+
try {
|
|
1555
|
+
return JSON.stringify(f, null, 2);
|
|
1556
|
+
} catch {
|
|
1557
|
+
return String(f);
|
|
1558
|
+
}
|
|
1559
|
+
}, d = () => l === "execute_code", u = (f) => {
|
|
1560
|
+
const m = `\`\`\`python
|
|
1561
|
+
${f}
|
|
1562
|
+
\`\`\``;
|
|
1563
|
+
return /* @__PURE__ */ t.jsx("div", { className: "markdown-block prose prose-sm max-w-none", children: /* @__PURE__ */ t.jsx(U, { remarkPlugins: [z], children: m }) });
|
|
1564
|
+
}, x = (f) => /* @__PURE__ */ t.jsx("div", { className: "markdown-block prose prose-sm max-w-none", children: /* @__PURE__ */ t.jsx(U, { remarkPlugins: [z], children: f }) });
|
|
1565
|
+
return c ? /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1566
|
+
/* @__PURE__ */ t.jsx(
|
|
1567
|
+
"div",
|
|
1568
|
+
{
|
|
1569
|
+
className: "fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity",
|
|
1570
|
+
onClick: p
|
|
1571
|
+
}
|
|
1572
|
+
),
|
|
1573
|
+
/* @__PURE__ */ t.jsxs("div", { className: "fixed right-0 top-0 bottom-0 w-[600px] max-w-[90vw] bg-white shadow-xl z-50 flex flex-col animate-slide-in-right", children: [
|
|
1574
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200", children: [
|
|
1575
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1576
|
+
a(),
|
|
1577
|
+
/* @__PURE__ */ t.jsx("h2", { className: "text-lg font-semibold text-gray-900", children: e })
|
|
1578
|
+
] }),
|
|
1579
|
+
/* @__PURE__ */ t.jsx(
|
|
1580
|
+
"button",
|
|
1581
|
+
{
|
|
1582
|
+
onClick: p,
|
|
1583
|
+
className: "w-8 h-8 flex items-center justify-center rounded-full hover:bg-gray-100 transition-colors",
|
|
1584
|
+
"aria-label": "关闭",
|
|
1585
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1586
|
+
"svg",
|
|
1587
|
+
{
|
|
1588
|
+
className: "w-5 h-5 text-gray-500",
|
|
1589
|
+
viewBox: "0 0 24 24",
|
|
1590
|
+
fill: "none",
|
|
1591
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1592
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1593
|
+
"path",
|
|
1594
|
+
{
|
|
1595
|
+
d: "M18 6L6 18M6 6L18 18",
|
|
1596
|
+
stroke: "currentColor",
|
|
1597
|
+
strokeWidth: "2",
|
|
1598
|
+
strokeLinecap: "round",
|
|
1599
|
+
strokeLinejoin: "round"
|
|
1600
|
+
}
|
|
1601
|
+
)
|
|
1602
|
+
}
|
|
1603
|
+
)
|
|
1604
|
+
}
|
|
1605
|
+
)
|
|
1606
|
+
] }),
|
|
1607
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: [
|
|
1608
|
+
d() ? /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1609
|
+
n != null && /* @__PURE__ */ t.jsxs("div", { className: "mb-6", children: [
|
|
1610
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输入" }),
|
|
1611
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-x-auto", children: u(typeof n == "string" ? n : i(n)) })
|
|
1612
|
+
] }),
|
|
1613
|
+
o != null && /* @__PURE__ */ t.jsxs("div", { children: [
|
|
1614
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输出" }),
|
|
1615
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-x-auto", children: x(typeof o == "string" ? o : i(o)) })
|
|
1616
|
+
] })
|
|
1617
|
+
] }) : /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1618
|
+
n != null && /* @__PURE__ */ t.jsxs("div", { className: "mb-6", children: [
|
|
1619
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输入" }),
|
|
1620
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4", children: /* @__PURE__ */ t.jsx("pre", { className: "text-sm text-gray-700 whitespace-pre-wrap break-words font-mono", children: i(n) }) })
|
|
1621
|
+
] }),
|
|
1622
|
+
o != null && /* @__PURE__ */ t.jsxs("div", { children: [
|
|
1623
|
+
/* @__PURE__ */ t.jsx("h3", { className: "text-sm font-bold text-gray-900 mb-3", children: "输出" }),
|
|
1624
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-4", children: /* @__PURE__ */ t.jsx("pre", { className: "text-sm text-gray-700 whitespace-pre-wrap break-words font-mono", children: i(o) }) })
|
|
1625
|
+
] })
|
|
1626
|
+
] }),
|
|
1627
|
+
n == null && o == null && /* @__PURE__ */ t.jsx("div", { className: "text-center text-gray-400 py-8", children: "暂无数据" })
|
|
1628
|
+
] })
|
|
1629
|
+
] }),
|
|
1630
|
+
/* @__PURE__ */ t.jsx("style", { children: `
|
|
1631
|
+
@keyframes slide-in-right {
|
|
1632
|
+
from {
|
|
1633
|
+
transform: translateX(100%);
|
|
1634
|
+
}
|
|
1635
|
+
to {
|
|
1636
|
+
transform: translateX(0);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
.animate-slide-in-right {
|
|
1640
|
+
animation: slide-in-right 0.3s ease-out;
|
|
1641
|
+
}
|
|
1642
|
+
` })
|
|
1643
|
+
] }) : null;
|
|
1644
|
+
}, Ve = ({ block: c }) => {
|
|
1645
|
+
const [p, l] = Be(!1), { icon: e, title: s, name: n, input: o, output: a } = c.content, i = () => e ? typeof e == "string" ? /* @__PURE__ */ t.jsx(
|
|
1646
|
+
"img",
|
|
1647
|
+
{
|
|
1648
|
+
src: e,
|
|
1649
|
+
alt: n,
|
|
1650
|
+
className: "w-5 h-5 flex-shrink-0",
|
|
1651
|
+
onError: (d) => {
|
|
1652
|
+
d.currentTarget.style.display = "none";
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
) : /* @__PURE__ */ t.jsx("div", { className: "w-5 h-5 flex-shrink-0", children: e }) : null;
|
|
1656
|
+
return /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
1657
|
+
/* @__PURE__ */ t.jsx("div", { className: "tool-block bg-white border border-[#d9d9d9] rounded-[6px] my-2", children: /* @__PURE__ */ t.jsxs(
|
|
1658
|
+
"div",
|
|
1659
|
+
{
|
|
1660
|
+
className: "flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-gray-50 transition-colors",
|
|
1661
|
+
onClick: () => l(!0),
|
|
1662
|
+
children: [
|
|
1663
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
1664
|
+
i(),
|
|
1665
|
+
/* @__PURE__ */ t.jsx("span", { className: "text-sm text-[rgba(0,0,0,0.65)] truncate", children: s })
|
|
1666
|
+
] }),
|
|
1667
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex items-center justify-center w-4 h-4 flex-shrink-0", children: /* @__PURE__ */ t.jsx(
|
|
1668
|
+
"svg",
|
|
1669
|
+
{
|
|
1670
|
+
className: "w-4 h-4 text-gray-400",
|
|
1671
|
+
viewBox: "0 0 24 24",
|
|
1672
|
+
fill: "none",
|
|
1673
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1674
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1675
|
+
"path",
|
|
1676
|
+
{
|
|
1677
|
+
d: "M9 18L15 12L9 6",
|
|
1678
|
+
stroke: "currentColor",
|
|
1679
|
+
strokeWidth: "2",
|
|
1680
|
+
strokeLinecap: "round",
|
|
1681
|
+
strokeLinejoin: "round"
|
|
1682
|
+
}
|
|
1683
|
+
)
|
|
1684
|
+
}
|
|
1685
|
+
) })
|
|
1686
|
+
]
|
|
1687
|
+
}
|
|
1688
|
+
) }),
|
|
1689
|
+
/* @__PURE__ */ t.jsx(
|
|
1690
|
+
Ut,
|
|
1691
|
+
{
|
|
1692
|
+
isOpen: p,
|
|
1693
|
+
onClose: () => l(!1),
|
|
1694
|
+
toolName: n,
|
|
1695
|
+
toolTitle: s,
|
|
1696
|
+
toolIcon: e,
|
|
1697
|
+
input: o,
|
|
1698
|
+
output: a
|
|
1699
|
+
}
|
|
1700
|
+
)
|
|
1701
|
+
] });
|
|
1702
|
+
}, zt = ({ block: c }) => {
|
|
1703
|
+
const { input: p, results: l } = c.content, e = {
|
|
1704
|
+
type: T.TOOL,
|
|
1705
|
+
content: {
|
|
1706
|
+
name: "web_search",
|
|
1707
|
+
title: `联网搜索:${p}`,
|
|
1708
|
+
icon: /* @__PURE__ */ t.jsx(
|
|
1709
|
+
"svg",
|
|
1710
|
+
{
|
|
1711
|
+
className: "w-5 h-5 text-blue-600",
|
|
1712
|
+
fill: "none",
|
|
1713
|
+
stroke: "currentColor",
|
|
1714
|
+
viewBox: "0 0 24 24",
|
|
1715
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1716
|
+
"path",
|
|
1717
|
+
{
|
|
1718
|
+
strokeLinecap: "round",
|
|
1719
|
+
strokeLinejoin: "round",
|
|
1720
|
+
strokeWidth: 2,
|
|
1721
|
+
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
1722
|
+
}
|
|
1723
|
+
)
|
|
1724
|
+
}
|
|
1725
|
+
),
|
|
1726
|
+
input: {
|
|
1727
|
+
query: p
|
|
1728
|
+
},
|
|
1729
|
+
output: {
|
|
1730
|
+
results: l.map((s) => ({
|
|
1731
|
+
title: s.title,
|
|
1732
|
+
content: s.content,
|
|
1733
|
+
link: s.link,
|
|
1734
|
+
media: s.media,
|
|
1735
|
+
icon: s.icon
|
|
1736
|
+
})),
|
|
1737
|
+
total: l.length
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
};
|
|
1741
|
+
return /* @__PURE__ */ t.jsx(Ve, { block: e });
|
|
1742
|
+
}, Jt = ({ message: c }) => {
|
|
1743
|
+
const p = c.role.type === P.USER, l = () => Array.isArray(c.content) ? /* @__PURE__ */ t.jsx("div", { className: "space-y-2", children: c.content.map((e, s) => {
|
|
1744
|
+
switch (e.type) {
|
|
1745
|
+
case T.TEXT:
|
|
1746
|
+
return /* @__PURE__ */ t.jsx(Wt, { block: e }, s);
|
|
1747
|
+
case T.MARKDOWN:
|
|
1748
|
+
return /* @__PURE__ */ t.jsx(Ft, { block: e }, s);
|
|
1749
|
+
case T.WEB_SEARCH:
|
|
1750
|
+
return /* @__PURE__ */ t.jsx(zt, { block: e }, s);
|
|
1751
|
+
case T.TOOL:
|
|
1752
|
+
return /* @__PURE__ */ t.jsx(Ve, { block: e }, s);
|
|
1753
|
+
default:
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1756
|
+
}) }) : /* @__PURE__ */ t.jsx("p", { className: "text-[14px] whitespace-pre-wrap break-words leading-[24px]", children: c.content });
|
|
1757
|
+
return /* @__PURE__ */ t.jsxs("div", { className: `flex ${p ? "justify-end" : "justify-start"} mb-4`, children: [
|
|
1758
|
+
!p && /* @__PURE__ */ t.jsx("div", { className: "w-[21px] h-[21px] mr-2 flex-shrink-0 mt-1", children: /* @__PURE__ */ t.jsx("img", { src: "/icons/assistant.svg", alt: "AI Assistant", className: "w-[21px] h-[21px]" }) }),
|
|
1759
|
+
/* @__PURE__ */ t.jsxs("div", { className: "flex flex-col gap-2 max-w-[calc(100%-40px)]", children: [
|
|
1760
|
+
p && c.applicationContext && c.applicationContext.title && /* @__PURE__ */ t.jsx("div", { className: "self-end", children: /* @__PURE__ */ t.jsx("span", { className: "inline-block bg-[rgba(18,110,227,0.04)] rounded-[8px] px-[14px] py-[5px] text-[12px] leading-[24px] text-[rgba(0,0,0,0.85)]", style: { fontFamily: "Noto Sans SC" }, children: c.applicationContext.title }) }),
|
|
1761
|
+
/* @__PURE__ */ t.jsx(
|
|
1762
|
+
"div",
|
|
1763
|
+
{
|
|
1764
|
+
className: `rounded-[8px] ${p ? "bg-[rgba(18,110,227,0.1)] text-[rgba(0,0,0,0.85)] px-[14px] py-[5px]" : "bg-white text-black px-4 py-3"}`,
|
|
1765
|
+
style: { fontFamily: "Noto Sans SC" },
|
|
1766
|
+
children: l()
|
|
1767
|
+
}
|
|
1768
|
+
)
|
|
1769
|
+
] })
|
|
1770
|
+
] });
|
|
1771
|
+
}, Vt = ({ messages: c }) => {
|
|
1772
|
+
const p = Le(null), l = () => {
|
|
1773
|
+
var e;
|
|
1774
|
+
(e = p.current) == null || e.scrollIntoView({ behavior: "smooth" });
|
|
1775
|
+
};
|
|
1776
|
+
return F(() => {
|
|
1777
|
+
l();
|
|
1778
|
+
}, [c]), /* @__PURE__ */ t.jsx("div", { className: "w-full flex justify-center", children: /* @__PURE__ */ t.jsxs("div", { className: "w-full max-w-[960px] px-5 py-3", children: [
|
|
1779
|
+
c.map((e) => /* @__PURE__ */ t.jsx(Jt, { message: e }, e.messageId)),
|
|
1780
|
+
/* @__PURE__ */ t.jsx("div", { ref: p })
|
|
1781
|
+
] }) });
|
|
1782
|
+
}, Kt = (c) => /* @__PURE__ */ t.jsx(
|
|
1783
|
+
"svg",
|
|
1784
|
+
{
|
|
1785
|
+
className: "w-3 h-3",
|
|
1786
|
+
fill: "none",
|
|
1787
|
+
stroke: "currentColor",
|
|
1788
|
+
viewBox: "0 0 24 24",
|
|
1789
|
+
...c,
|
|
1790
|
+
children: /* @__PURE__ */ t.jsx(
|
|
1791
|
+
"path",
|
|
1792
|
+
{
|
|
1793
|
+
strokeLinecap: "round",
|
|
1794
|
+
strokeLinejoin: "round",
|
|
1795
|
+
strokeWidth: 2,
|
|
1796
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
1797
|
+
}
|
|
1798
|
+
)
|
|
1799
|
+
}
|
|
1800
|
+
), qt = (c) => /* @__PURE__ */ t.jsx(
|
|
1801
|
+
"svg",
|
|
1802
|
+
{
|
|
1803
|
+
className: "w-4 h-4 text-white",
|
|
1804
|
+
fill: "currentColor",
|
|
1805
|
+
viewBox: "0 0 24 24",
|
|
1806
|
+
...c,
|
|
1807
|
+
children: /* @__PURE__ */ t.jsx("rect", { x: "6", y: "6", width: "12", height: "12" })
|
|
1808
|
+
}
|
|
1809
|
+
), Qt = ({ disabled: c = !1, ...p }) => /* @__PURE__ */ t.jsxs("svg", { width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", ...p, children: [
|
|
1810
|
+
/* @__PURE__ */ t.jsx("circle", { cx: "16", cy: "16", r: "16", fill: "#1890ff", opacity: c ? "0.3" : "1" }),
|
|
1811
|
+
/* @__PURE__ */ t.jsx("path", { d: "M22 16L14 12V20L22 16Z", fill: "white" })
|
|
1812
|
+
] }), Yt = (c) => /* @__PURE__ */ t.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", className: "mt-1.5 flex-shrink-0", ...c, children: [
|
|
1813
|
+
/* @__PURE__ */ t.jsx("circle", { cx: "6", cy: "6", r: "5", stroke: "#1890ff", strokeWidth: "1.5", fill: "none" }),
|
|
1814
|
+
/* @__PURE__ */ t.jsx("path", { d: "M6 3V6L8 8", stroke: "#1890ff", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
1815
|
+
] }), Xt = ({
|
|
1816
|
+
value: c,
|
|
1817
|
+
onChange: p,
|
|
1818
|
+
onSend: l,
|
|
1819
|
+
context: e,
|
|
1820
|
+
onRemoveContext: s,
|
|
1821
|
+
disabled: n = !1,
|
|
1822
|
+
isStreaming: o = !1,
|
|
1823
|
+
onStop: a
|
|
1824
|
+
}) => {
|
|
1825
|
+
const i = (d) => {
|
|
1826
|
+
d.key === "Enter" && !d.shiftKey && (d.preventDefault(), l());
|
|
1827
|
+
};
|
|
1828
|
+
return /* @__PURE__ */ t.jsx("div", { className: "w-full flex justify-center", children: /* @__PURE__ */ t.jsxs("div", { className: "w-full max-w-[960px] px-5 pb-6", children: [
|
|
1829
|
+
e && e.title && /* @__PURE__ */ t.jsxs("div", { className: "mb-2 bg-[rgba(18,110,227,0.04)] rounded-lg px-4 py-2 flex items-center", children: [
|
|
1830
|
+
/* @__PURE__ */ t.jsx("p", { className: "text-[12px] leading-6 text-[rgba(0,0,0,0.85)] truncate", style: { fontFamily: "Noto Sans SC" }, children: e.title }),
|
|
1831
|
+
/* @__PURE__ */ t.jsx(
|
|
1832
|
+
"button",
|
|
1833
|
+
{
|
|
1834
|
+
onClick: s,
|
|
1835
|
+
className: "ml-auto text-[rgba(0,0,0,0.45)] hover:text-[rgba(0,0,0,0.85)] transition-colors flex-shrink-0",
|
|
1836
|
+
title: "移除上下文",
|
|
1837
|
+
children: /* @__PURE__ */ t.jsx(Kt, {})
|
|
1838
|
+
}
|
|
1839
|
+
)
|
|
1840
|
+
] }),
|
|
1841
|
+
/* @__PURE__ */ t.jsxs("div", { className: "relative bg-white border-[1.5px] border-solid border-[#3b9be0] rounded-[12px] overflow-hidden", children: [
|
|
1842
|
+
/* @__PURE__ */ t.jsx(
|
|
1843
|
+
"textarea",
|
|
1844
|
+
{
|
|
1845
|
+
value: c,
|
|
1846
|
+
onChange: (d) => p(d.target.value),
|
|
1847
|
+
onKeyDown: i,
|
|
1848
|
+
placeholder: "请输入要查找的内容",
|
|
1849
|
+
disabled: n,
|
|
1850
|
+
className: "w-full h-[56px] resize-none px-4 py-3 text-[14px] leading-[22px] text-black placeholder:text-[rgba(0,0,0,0.3)] focus:outline-none disabled:bg-gray-50 disabled:cursor-not-allowed",
|
|
1851
|
+
style: { fontFamily: "Noto Sans SC" },
|
|
1852
|
+
maxLength: 4e3
|
|
1853
|
+
}
|
|
1854
|
+
),
|
|
1855
|
+
o ? (
|
|
1856
|
+
// 停止按钮:在接收 AI 流式响应时显示
|
|
1857
|
+
/* @__PURE__ */ t.jsx(
|
|
1858
|
+
"button",
|
|
1859
|
+
{
|
|
1860
|
+
onClick: a,
|
|
1861
|
+
className: "absolute bottom-3 right-4 w-8 h-8 flex items-center justify-center bg-red-500 hover:bg-red-600 rounded transition-colors",
|
|
1862
|
+
title: "停止响应",
|
|
1863
|
+
children: /* @__PURE__ */ t.jsx(qt, {})
|
|
1864
|
+
}
|
|
1865
|
+
)
|
|
1866
|
+
) : (
|
|
1867
|
+
// 发送按钮:正常状态下显示
|
|
1868
|
+
/* @__PURE__ */ t.jsx(
|
|
1869
|
+
"button",
|
|
1870
|
+
{
|
|
1871
|
+
onClick: l,
|
|
1872
|
+
disabled: n || !c.trim(),
|
|
1873
|
+
className: "absolute bottom-3 right-4 w-8 h-8 flex items-center justify-center disabled:opacity-30 disabled:cursor-not-allowed transition-opacity",
|
|
1874
|
+
title: n ? "正在发送..." : "发送消息",
|
|
1875
|
+
children: /* @__PURE__ */ t.jsx(Qt, { disabled: n || !c.trim() })
|
|
1876
|
+
}
|
|
1877
|
+
)
|
|
1878
|
+
)
|
|
1879
|
+
] }),
|
|
1880
|
+
/* @__PURE__ */ t.jsx("p", { className: "mt-2 text-center text-[12px] leading-[18px] text-[rgba(0,0,0,0.55)]", style: { fontFamily: "Noto Sans SC" }, children: "回答的内容由 AI 生成,不能保证完全真实准确,请仔细甄别" })
|
|
1881
|
+
] }) });
|
|
1882
|
+
}, Gt = ({
|
|
1883
|
+
onQuestionClick: c,
|
|
1884
|
+
prologue: p,
|
|
1885
|
+
predefinedQuestions: l
|
|
1886
|
+
}) => {
|
|
1887
|
+
const e = l || [], s = (n) => {
|
|
1888
|
+
c && c(n);
|
|
1889
|
+
};
|
|
1890
|
+
return /* @__PURE__ */ t.jsx("div", { className: "w-full flex justify-center", children: /* @__PURE__ */ t.jsxs("div", { className: "w-full max-w-[960px] px-5 py-8", children: [
|
|
1891
|
+
p && /* @__PURE__ */ t.jsx("p", { className: "text-[20px] leading-normal text-[rgba(0,0,0,0.85)] font-normal mb-10", style: { fontFamily: "Noto Sans SC" }, children: p }),
|
|
1892
|
+
e.length > 0 && /* @__PURE__ */ t.jsx("div", { className: "grid grid-cols-4 gap-3", children: e.map((n, o) => /* @__PURE__ */ t.jsxs(
|
|
1893
|
+
"button",
|
|
1894
|
+
{
|
|
1895
|
+
onClick: () => s(n),
|
|
1896
|
+
className: "bg-white border border-[rgba(0,0,0,0.1)] rounded-[6px] px-4 py-3 text-left text-[14px] leading-[22px] text-[rgba(0,0,0,0.85)] hover:border-[#3b9be0] hover:bg-[rgba(18,110,227,0.04)] transition-all flex items-start gap-2",
|
|
1897
|
+
style: { fontFamily: "Noto Sans SC" },
|
|
1898
|
+
children: [
|
|
1899
|
+
/* @__PURE__ */ t.jsx(Yt, {}),
|
|
1900
|
+
/* @__PURE__ */ t.jsx("span", { children: n })
|
|
1901
|
+
]
|
|
1902
|
+
},
|
|
1903
|
+
o
|
|
1904
|
+
)) })
|
|
1905
|
+
] }) });
|
|
1906
|
+
};
|
|
1907
|
+
class Ht extends le {
|
|
1908
|
+
/**
|
|
1909
|
+
* 实现 React.Component.render() 方法
|
|
1910
|
+
* 渲染 Assistant 模式的界面
|
|
1911
|
+
*/
|
|
1912
|
+
render() {
|
|
1913
|
+
if (!this.props.visible)
|
|
1914
|
+
return null;
|
|
1915
|
+
const { messages: p, textInput: l, applicationContext: e, isSending: s, onboardingInfo: n, isLoadingOnboarding: o, streamingMessageId: a } = this.state, i = p.length === 0, d = a !== null;
|
|
1916
|
+
return /* @__PURE__ */ t.jsxs("div", { className: "flex flex-col h-full w-full bg-white", children: [
|
|
1917
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex-1 overflow-y-auto bg-gray-50", children: i ? o ? (
|
|
1918
|
+
// 加载中,显示加载提示
|
|
1919
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ t.jsxs("div", { className: "text-center", children: [
|
|
1920
|
+
/* @__PURE__ */ t.jsx("div", { className: "inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mb-4" }),
|
|
1921
|
+
/* @__PURE__ */ t.jsx("p", { className: "text-sm text-gray-500", children: "正在加载..." })
|
|
1922
|
+
] }) })
|
|
1923
|
+
) : (
|
|
1924
|
+
// 加载完成,显示开场白
|
|
1925
|
+
/* @__PURE__ */ t.jsx(
|
|
1926
|
+
Gt,
|
|
1927
|
+
{
|
|
1928
|
+
onQuestionClick: this.handleQuestionClick,
|
|
1929
|
+
prologue: n == null ? void 0 : n.prologue,
|
|
1930
|
+
predefinedQuestions: n == null ? void 0 : n.predefinedQuestions
|
|
1931
|
+
}
|
|
1932
|
+
)
|
|
1933
|
+
) : /* @__PURE__ */ t.jsx(Vt, { messages: p }) }),
|
|
1934
|
+
/* @__PURE__ */ t.jsx("div", { className: "bg-white border-t border-gray-100", children: /* @__PURE__ */ t.jsx(
|
|
1935
|
+
Xt,
|
|
1936
|
+
{
|
|
1937
|
+
value: l,
|
|
1938
|
+
onChange: this.setTextInput,
|
|
1939
|
+
onSend: this.handleSend,
|
|
1940
|
+
context: e,
|
|
1941
|
+
onRemoveContext: this.removeApplicationContext,
|
|
1942
|
+
disabled: s,
|
|
1943
|
+
isStreaming: d,
|
|
1944
|
+
onStop: this.handleStop
|
|
1945
|
+
}
|
|
1946
|
+
) })
|
|
1947
|
+
] });
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
function Ke(c) {
|
|
1951
|
+
return class extends c {
|
|
1952
|
+
constructor(...e) {
|
|
1953
|
+
super(...e);
|
|
1954
|
+
/** 服务端基础地址 */
|
|
1955
|
+
S(this, "dipBaseUrl");
|
|
1956
|
+
/** Agent ID */
|
|
1957
|
+
S(this, "dipId");
|
|
1958
|
+
/** agent 版本 */
|
|
1959
|
+
S(this, "dipVersion");
|
|
1960
|
+
/** 智能体执行引擎版本 */
|
|
1961
|
+
S(this, "dipExecutorVersion");
|
|
1962
|
+
/** 业务域 */
|
|
1963
|
+
S(this, "dipBusinessDomain");
|
|
1964
|
+
/** DIP 调用接口时携带的令牌 */
|
|
1965
|
+
S(this, "dipToken");
|
|
1966
|
+
/** DIP 刷新 token 的方法 */
|
|
1967
|
+
S(this, "dipRefreshToken");
|
|
1968
|
+
const s = e[0];
|
|
1969
|
+
this.dipBaseUrl = s.baseUrl || "https://dip.aishu.cn/api/agent-app/v1", this.dipId = s.agentId, this.dipVersion = s.agentVersion || "latest", this.dipExecutorVersion = s.executorVersion || "v2", this.dipBusinessDomain = s.businessDomain || "bd_public", this.dipToken = s.token || "", this.dipRefreshToken = s.refreshToken, s.bearerToken && !s.token && (this.dipToken = s.bearerToken.replace(/^Bearer\s+/i, ""));
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* 获取开场白和预置问题
|
|
1973
|
+
* 调用 AISHU DIP 的 agent-factory API 获取智能体配置信息,提取开场白和预置问题
|
|
1974
|
+
* API 端点: GET /api/agent-factory/v3/agent-market/agent/{agent_id}/version/v0
|
|
1975
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
1976
|
+
* @returns 返回开场白信息,包含开场白文案和预置问题
|
|
1977
|
+
*/
|
|
1978
|
+
async getOnboardingInfo() {
|
|
1979
|
+
try {
|
|
1980
|
+
console.log("正在获取 DIP 配置...");
|
|
1981
|
+
let e;
|
|
1982
|
+
if (this.dipBaseUrl.startsWith("http://") || this.dipBaseUrl.startsWith("https://")) {
|
|
1983
|
+
const x = new URL(this.dipBaseUrl);
|
|
1984
|
+
e = `${x.protocol}//${x.host}/api/agent-factory/v3/agent-market/agent/${encodeURIComponent(this.dipId)}/version/v0`;
|
|
1985
|
+
} else
|
|
1986
|
+
e = `/api/agent-factory/v3/agent-market/agent/${encodeURIComponent(this.dipId)}/version/v0`;
|
|
1987
|
+
console.log("调用 agent-factory API:", e);
|
|
1988
|
+
const n = (await this.executeDataAgentWithTokenRefresh(async () => {
|
|
1989
|
+
const x = await fetch(e, {
|
|
1990
|
+
method: "GET",
|
|
1991
|
+
headers: {
|
|
1992
|
+
Authorization: `Bearer ${this.dipToken}`,
|
|
1993
|
+
"Content-Type": "application/json",
|
|
1994
|
+
"x-business-domain": this.dipBusinessDomain
|
|
1995
|
+
}
|
|
1996
|
+
});
|
|
1997
|
+
if (!x.ok) {
|
|
1998
|
+
const f = await x.text(), m = new Error(`获取 DIP 配置失败: ${x.status} - ${f}`);
|
|
1999
|
+
throw m.status = x.status, m.body = f, m;
|
|
2000
|
+
}
|
|
2001
|
+
return await x.json();
|
|
2002
|
+
})).config || {}, o = n.opening_remark_config || {}, a = n.preset_questions || [];
|
|
2003
|
+
let i = "你好!我是数据智能体助手,我可以帮你分析数据、回答问题。";
|
|
2004
|
+
o.type === "fixed" && o.fixed_opening_remark && (i = o.fixed_opening_remark);
|
|
2005
|
+
const d = a.map((x) => x.question).filter((x) => typeof x == "string" && x.trim().length > 0);
|
|
2006
|
+
return {
|
|
2007
|
+
prologue: i,
|
|
2008
|
+
predefinedQuestions: d
|
|
2009
|
+
};
|
|
2010
|
+
} catch (e) {
|
|
2011
|
+
return console.error("获取 DIP 配置失败:", e), {
|
|
2012
|
+
prologue: "你好!我是数据智能体助手,我可以帮你分析数据、回答问题。",
|
|
2013
|
+
predefinedQuestions: []
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* 创建新的会话
|
|
2019
|
+
* 调用 DIP API 创建新的会话,返回会话 ID
|
|
2020
|
+
* API 端点: POST /app/{agent_id}/conversation
|
|
2021
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2022
|
+
* @returns 返回新创建的会话 ID
|
|
2023
|
+
*/
|
|
2024
|
+
async generateConversation() {
|
|
2025
|
+
var e, s;
|
|
2026
|
+
try {
|
|
2027
|
+
console.log("正在创建 DIP 会话...");
|
|
2028
|
+
const n = {
|
|
2029
|
+
agent_id: this.dipId,
|
|
2030
|
+
agent_version: "latest"
|
|
2031
|
+
}, o = await this.executeDataAgentWithTokenRefresh(async () => {
|
|
2032
|
+
const i = await fetch(
|
|
2033
|
+
`${this.dipBaseUrl}/app/${this.dipId}/conversation`,
|
|
2034
|
+
{
|
|
2035
|
+
method: "POST",
|
|
2036
|
+
headers: {
|
|
2037
|
+
"Content-Type": "application/json",
|
|
2038
|
+
Authorization: `Bearer ${this.dipToken}`
|
|
2039
|
+
},
|
|
2040
|
+
body: JSON.stringify(n)
|
|
2041
|
+
}
|
|
2042
|
+
);
|
|
2043
|
+
if (!i.ok) {
|
|
2044
|
+
const d = await i.text(), u = new Error(`创建 DIP 会话失败: ${i.status} - ${d}`);
|
|
2045
|
+
throw u.status = i.status, u.body = d, u;
|
|
2046
|
+
}
|
|
2047
|
+
return await i.json();
|
|
2048
|
+
}), a = ((e = o.data) == null ? void 0 : e.id) || o.id || "";
|
|
2049
|
+
return console.log("DIP 会话创建成功, conversationID:", a, "ttl:", ((s = o.data) == null ? void 0 : s.ttl) || o.ttl), a;
|
|
2050
|
+
} catch (n) {
|
|
2051
|
+
return console.error("创建 DIP 会话失败:", n), "";
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
2055
|
+
* 调用 DIP API 发送消息(流式)
|
|
2056
|
+
* 该方法实现了完整的消息发送逻辑,子类无需覆盖
|
|
2057
|
+
* @param text 用户输入
|
|
2058
|
+
* @param ctx 应用上下文
|
|
2059
|
+
* @param conversationID 发送的对话消息所属的会话 ID
|
|
2060
|
+
* @returns 返回助手消息
|
|
2061
|
+
*/
|
|
2062
|
+
async sendMessage(e, s, n) {
|
|
2063
|
+
var m;
|
|
2064
|
+
if (!this.dipBaseUrl)
|
|
2065
|
+
throw new Error("DIP baseUrl 不能为空");
|
|
2066
|
+
let o = e;
|
|
2067
|
+
s && s.title && (o = `【上下文: ${s.title}】
|
|
2068
|
+
${JSON.stringify(s.data, null, 2)}
|
|
2069
|
+
|
|
2070
|
+
${e}`);
|
|
2071
|
+
const a = {
|
|
2072
|
+
agent_id: this.dipId,
|
|
2073
|
+
agent_version: this.dipVersion,
|
|
2074
|
+
executor_version: this.dipExecutorVersion,
|
|
2075
|
+
query: o,
|
|
2076
|
+
stream: !0,
|
|
2077
|
+
custom_querys: s == null ? void 0 : s.data,
|
|
2078
|
+
conversation_id: n || void 0
|
|
2079
|
+
}, i = await this.executeDataAgentWithTokenRefresh(async () => {
|
|
2080
|
+
const y = await fetch(
|
|
2081
|
+
`${this.dipBaseUrl}/app/${this.dipId}/chat/completion`,
|
|
2082
|
+
{
|
|
2083
|
+
method: "POST",
|
|
2084
|
+
headers: {
|
|
2085
|
+
"Content-Type": "application/json",
|
|
2086
|
+
Accept: "text/event-stream",
|
|
2087
|
+
Authorization: `Bearer ${this.dipToken}`
|
|
2088
|
+
},
|
|
2089
|
+
body: JSON.stringify(a)
|
|
2090
|
+
}
|
|
2091
|
+
);
|
|
2092
|
+
if (!y.ok) {
|
|
2093
|
+
const b = await y.text(), N = new Error(`DIP API 调用失败: ${y.status} ${b}`);
|
|
2094
|
+
throw N.status = y.status, N.body = b, N;
|
|
2095
|
+
}
|
|
2096
|
+
return y;
|
|
2097
|
+
}), d = `assistant-${Date.now()}`, u = {
|
|
2098
|
+
messageId: d,
|
|
2099
|
+
content: [],
|
|
2100
|
+
role: {
|
|
2101
|
+
name: "AI 助手",
|
|
2102
|
+
type: P.ASSISTANT,
|
|
2103
|
+
avatar: ""
|
|
2104
|
+
}
|
|
2105
|
+
};
|
|
2106
|
+
this.setState((y) => ({
|
|
2107
|
+
messages: [...y.messages, u],
|
|
2108
|
+
streamingMessageId: d
|
|
2109
|
+
}));
|
|
2110
|
+
const x = (m = i.body) == null ? void 0 : m.getReader();
|
|
2111
|
+
if (!x)
|
|
2112
|
+
throw new Error("无法获取流式响应");
|
|
2113
|
+
return await this.handleStreamResponse(x, d), this.state.messages.find((y) => y.messageId === d) || u;
|
|
2114
|
+
}
|
|
2115
|
+
/**
|
|
2116
|
+
* 将 API 接口返回的 EventStream 增量解析成完整的 AssistantMessage 对象
|
|
2117
|
+
* 根据设计文档实现白名单机制和 JSONPath 处理
|
|
2118
|
+
* @param eventMessage 接收到的一条 Event Message
|
|
2119
|
+
* @param prev 上一次增量更新后的 AssistantMessage 对象
|
|
2120
|
+
* @param messageId 当前正在更新的消息 ID
|
|
2121
|
+
* @returns 返回更新后的 AssistantMessage 对象
|
|
2122
|
+
*/
|
|
2123
|
+
reduceAssistantMessage(e, s, n) {
|
|
2124
|
+
try {
|
|
2125
|
+
const o = typeof e == "string" ? JSON.parse(e) : e, a = this.parseEventMessage(o);
|
|
2126
|
+
if (a.action === "end")
|
|
2127
|
+
return console.log("EventStream 结束"), s;
|
|
2128
|
+
const i = this.keyToJSONPath(a.key || []), d = this.getWhitelistEntry(a.action || "", i);
|
|
2129
|
+
if (!d)
|
|
2130
|
+
return console.log("跳过非白名单事件:", a.action, i), s;
|
|
2131
|
+
let u = JSON.parse(JSON.stringify(s || {}));
|
|
2132
|
+
return a.action === "upsert" ? u = this.applyUpsert(u, a.key || [], a.content) : a.action === "append" && (u = this.applyAppend(u, a.key || [], a.content)), d.postProcess && d.postProcess(u, a.content, n), u;
|
|
2133
|
+
} catch (o) {
|
|
2134
|
+
return console.error("解析 DIP 事件失败:", o, e), s;
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
/**
|
|
2138
|
+
* 解析原始事件为 EventMessage
|
|
2139
|
+
*/
|
|
2140
|
+
parseEventMessage(e) {
|
|
2141
|
+
if (e.data) {
|
|
2142
|
+
const s = typeof e.data == "string" ? e.data : JSON.stringify(e.data);
|
|
2143
|
+
try {
|
|
2144
|
+
const n = JSON.parse(s);
|
|
2145
|
+
return {
|
|
2146
|
+
seq_id: n.seq_id || n.seq,
|
|
2147
|
+
key: n.key,
|
|
2148
|
+
action: n.action,
|
|
2149
|
+
content: n.content
|
|
2150
|
+
};
|
|
2151
|
+
} catch {
|
|
2152
|
+
return e;
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
return {
|
|
2156
|
+
seq_id: e.seq_id || e.seq,
|
|
2157
|
+
key: e.key,
|
|
2158
|
+
action: e.action,
|
|
2159
|
+
content: e.content
|
|
2160
|
+
};
|
|
2161
|
+
}
|
|
2162
|
+
/**
|
|
2163
|
+
* 将 key 数组转换为 JSONPath 字符串
|
|
2164
|
+
* 例如: ["message", "content", "final_answer", "answer", "text"]
|
|
2165
|
+
* => "message.content.final_answer.answer.text"
|
|
2166
|
+
*/
|
|
2167
|
+
keyToJSONPath(e) {
|
|
2168
|
+
return e.map((s, n) => typeof s == "number" ? `[${s}]` : n === 0 ? s : `.${s}`).join("").replace(/\.\[/g, "[");
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* 白名单定义
|
|
2172
|
+
* 根据设计文档 3.2 Event Message 白名单
|
|
2173
|
+
*
|
|
2174
|
+
* 注意:postProcess 方法需要调用 appendMarkdownBlock 和 appendWebSearchBlock
|
|
2175
|
+
* 这些方法需要在子类中实现
|
|
2176
|
+
*/
|
|
2177
|
+
getWhitelistEntry(e, s) {
|
|
2178
|
+
const n = {
|
|
2179
|
+
"upsert:error": {},
|
|
2180
|
+
"upsert:message": {},
|
|
2181
|
+
"append:message.content.final_answer.answer.text": {
|
|
2182
|
+
postProcess: (d, u, x) => {
|
|
2183
|
+
var m, y, b, N;
|
|
2184
|
+
const f = ((N = (b = (y = (m = d.message) == null ? void 0 : m.content) == null ? void 0 : y.final_answer) == null ? void 0 : b.answer) == null ? void 0 : N.text) || "";
|
|
2185
|
+
this.appendMarkdownBlock(x, f);
|
|
2186
|
+
}
|
|
2187
|
+
},
|
|
2188
|
+
"upsert:message.content.final_answer.answer_type_other": {
|
|
2189
|
+
postProcess: (d, u, x) => {
|
|
2190
|
+
this.processFinalAnswerTypeOther(u, x);
|
|
2191
|
+
}
|
|
2192
|
+
},
|
|
2193
|
+
"append:message.content.middle_answer.progress": {
|
|
2194
|
+
postProcess: (d, u, x) => {
|
|
2195
|
+
this.processMiddleAnswerProgress(u, x);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
}, o = /^message\.content\.middle_answer\.progress\[\d+\]$/, a = /^message\.content\.middle_answer\.progress\[\d+\]\.answer$/;
|
|
2199
|
+
if (e === "append" && o.test(s))
|
|
2200
|
+
return n["append:message.content.middle_answer.progress"];
|
|
2201
|
+
if (e === "append" && a.test(s))
|
|
2202
|
+
return {
|
|
2203
|
+
postProcess: (d, u, x) => {
|
|
2204
|
+
var m, y, b;
|
|
2205
|
+
const f = ((b = (y = (m = d.message) == null ? void 0 : m.content) == null ? void 0 : y.middle_answer) == null ? void 0 : b.progress) || [];
|
|
2206
|
+
if (f.length > 0) {
|
|
2207
|
+
const N = f[f.length - 1];
|
|
2208
|
+
if (N.stage === "llm") {
|
|
2209
|
+
const D = N.answer || "";
|
|
2210
|
+
this.appendMarkdownBlock(x, D);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
const i = `${e}:${s}`;
|
|
2216
|
+
return n[i] || null;
|
|
2217
|
+
}
|
|
2218
|
+
/**
|
|
2219
|
+
* 从 Progress 对象中提取 Web 搜索查询
|
|
2220
|
+
* 根据 OpenAPI 规范,搜索数据在 answer.choices[0].message.tool_calls 中
|
|
2221
|
+
* tool_calls[0] 是 SearchIntent(输入),tool_calls[1] 是 SearchResult(输出)
|
|
2222
|
+
*/
|
|
2223
|
+
extractWebSearchQuery(e) {
|
|
2224
|
+
var s, n, o, a;
|
|
2225
|
+
try {
|
|
2226
|
+
const i = (a = (o = (n = (s = e == null ? void 0 : e.answer) == null ? void 0 : s.choices) == null ? void 0 : n[0]) == null ? void 0 : o.message) == null ? void 0 : a.tool_calls;
|
|
2227
|
+
if (!i || !Array.isArray(i) || i.length < 2)
|
|
2228
|
+
return null;
|
|
2229
|
+
const d = i[0], u = d == null ? void 0 : d.search_intent, x = Array.isArray(u) ? u[0] : u, f = (x == null ? void 0 : x.query) || (x == null ? void 0 : x.keywords) || "", m = i[1], y = m == null ? void 0 : m.search_result;
|
|
2230
|
+
if (!y || !Array.isArray(y))
|
|
2231
|
+
return null;
|
|
2232
|
+
const b = y.map((N) => ({
|
|
2233
|
+
content: N.content || "",
|
|
2234
|
+
icon: N.icon || "",
|
|
2235
|
+
link: N.link || "",
|
|
2236
|
+
media: N.media || "",
|
|
2237
|
+
title: N.title || ""
|
|
2238
|
+
}));
|
|
2239
|
+
return {
|
|
2240
|
+
input: f,
|
|
2241
|
+
results: b
|
|
2242
|
+
};
|
|
2243
|
+
} catch (i) {
|
|
2244
|
+
return console.error("提取 Web 搜索查询失败:", i), null;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* 处理技能调用的统一方法
|
|
2249
|
+
* 根据设计文档 3.2 Event Message 白名单中的后处理逻辑
|
|
2250
|
+
* @param skillInfo 技能信息
|
|
2251
|
+
* @param answer 技能执行的 answer 字段
|
|
2252
|
+
* @param messageId 消息 ID
|
|
2253
|
+
*/
|
|
2254
|
+
processSkillExecution(e, s, n) {
|
|
2255
|
+
if (!(e != null && e.name))
|
|
2256
|
+
return;
|
|
2257
|
+
const o = e.name;
|
|
2258
|
+
if (o === "zhipu_search_tool") {
|
|
2259
|
+
const a = this.extractWebSearchQueryFromAnswer(s);
|
|
2260
|
+
a && this.appendWebSearchBlock(n, a);
|
|
2261
|
+
} else if (o === "json2plot") {
|
|
2262
|
+
const a = this.extractChartDataFromArgs(e.args);
|
|
2263
|
+
a && this.appendJson2plotBlock(n, a);
|
|
2264
|
+
} else if (o === "execute_code") {
|
|
2265
|
+
const a = this.extractExecuteCodeResult(e.args, s);
|
|
2266
|
+
a && this.appendExecuteCodeBlock(n, a);
|
|
2267
|
+
} else
|
|
2268
|
+
this.appendMarkdownBlock(n, `调用工具: ${o}`);
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* 处理 final_answer.answer_type_other
|
|
2272
|
+
* 根据设计文档 3.2 Event Message 白名单中的后处理逻辑
|
|
2273
|
+
* @param content OtherTypeAnswer 对象
|
|
2274
|
+
* @param messageId 消息 ID
|
|
2275
|
+
*/
|
|
2276
|
+
processFinalAnswerTypeOther(e, s) {
|
|
2277
|
+
(e == null ? void 0 : e.stage) === "skill" && this.processSkillExecution(e.skill_info, e.answer, s);
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* 处理 middle_answer.progress 中的一个元素
|
|
2281
|
+
* 根据设计文档 3.2 Event Message 白名单中的后处理逻辑
|
|
2282
|
+
* @param content Progress 对象
|
|
2283
|
+
* @param messageId 消息 ID
|
|
2284
|
+
*/
|
|
2285
|
+
processMiddleAnswerProgress(e, s) {
|
|
2286
|
+
if ((e == null ? void 0 : e.stage) === "skill")
|
|
2287
|
+
this.processSkillExecution(e.skill_info, e.answer, s);
|
|
2288
|
+
else if ((e == null ? void 0 : e.stage) === "llm") {
|
|
2289
|
+
const n = e.answer || "";
|
|
2290
|
+
this.appendMarkdownBlock(s, n);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
/**
|
|
2294
|
+
* 从 answer.choices 中提取 Web 搜索查询
|
|
2295
|
+
* 用于处理 final_answer.answer_type_other 和 middle_answer.progress 中的搜索结果
|
|
2296
|
+
*/
|
|
2297
|
+
extractWebSearchQueryFromAnswer(e) {
|
|
2298
|
+
var s, n, o;
|
|
2299
|
+
try {
|
|
2300
|
+
const a = (o = (n = (s = e == null ? void 0 : e.choices) == null ? void 0 : s[0]) == null ? void 0 : n.message) == null ? void 0 : o.tool_calls;
|
|
2301
|
+
if (!a || !Array.isArray(a) || a.length < 2)
|
|
2302
|
+
return null;
|
|
2303
|
+
const i = a[0], d = i == null ? void 0 : i.search_intent, u = Array.isArray(d) ? d[0] : d, x = (u == null ? void 0 : u.query) || (u == null ? void 0 : u.keywords) || "", f = a[1], m = f == null ? void 0 : f.search_result;
|
|
2304
|
+
if (!m || !Array.isArray(m))
|
|
2305
|
+
return null;
|
|
2306
|
+
const y = m.map((b) => ({
|
|
2307
|
+
content: b.content || "",
|
|
2308
|
+
icon: b.icon || "",
|
|
2309
|
+
link: b.link || "",
|
|
2310
|
+
media: b.media || "",
|
|
2311
|
+
title: b.title || ""
|
|
2312
|
+
}));
|
|
2313
|
+
return {
|
|
2314
|
+
input: x,
|
|
2315
|
+
results: y
|
|
2316
|
+
};
|
|
2317
|
+
} catch (a) {
|
|
2318
|
+
return console.error("提取 Web 搜索查询失败:", a), null;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* 从 skill_info.args 中提取图表数据
|
|
2323
|
+
* 用于处理 json2plot 工具的输出
|
|
2324
|
+
*/
|
|
2325
|
+
extractChartDataFromArgs(e) {
|
|
2326
|
+
if (!e || !Array.isArray(e))
|
|
2327
|
+
return null;
|
|
2328
|
+
try {
|
|
2329
|
+
const s = {};
|
|
2330
|
+
for (const n of e)
|
|
2331
|
+
if (n.name && n.value !== void 0)
|
|
2332
|
+
try {
|
|
2333
|
+
s[n.name] = JSON.parse(n.value);
|
|
2334
|
+
} catch {
|
|
2335
|
+
s[n.name] = n.value;
|
|
2336
|
+
}
|
|
2337
|
+
return s;
|
|
2338
|
+
} catch (s) {
|
|
2339
|
+
return console.error("提取图表数据失败:", s), null;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
/**
|
|
2343
|
+
* 从 skill_info.args 和 answer 中提取代码执行结果
|
|
2344
|
+
* 用于处理 execute_code 工具的输入和输出
|
|
2345
|
+
* @param args skill_info.args 数组,包含执行的代码
|
|
2346
|
+
* @param answer 技能执行的 answer 字段,包含执行结果
|
|
2347
|
+
* @returns ExecuteCodeResult 对象,包含 input 和 output
|
|
2348
|
+
*/
|
|
2349
|
+
extractExecuteCodeResult(e, s) {
|
|
2350
|
+
var n, o;
|
|
2351
|
+
try {
|
|
2352
|
+
let a = "";
|
|
2353
|
+
if (e && Array.isArray(e)) {
|
|
2354
|
+
const d = e.find(
|
|
2355
|
+
(u) => u.name === "code" || u.name === "script" || u.type === "str"
|
|
2356
|
+
);
|
|
2357
|
+
a = (d == null ? void 0 : d.value) || "";
|
|
2358
|
+
}
|
|
2359
|
+
const i = ((o = (n = s == null ? void 0 : s.result) == null ? void 0 : n.result) == null ? void 0 : o.stdout) || "执行完成";
|
|
2360
|
+
return a ? {
|
|
2361
|
+
input: a,
|
|
2362
|
+
output: i
|
|
2363
|
+
} : null;
|
|
2364
|
+
} catch (a) {
|
|
2365
|
+
return console.error("提取代码执行结果失败:", a), null;
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
/**
|
|
2369
|
+
* 将技能调用或 LLM 回答的内容追加到消息中
|
|
2370
|
+
* 用于历史消息解析,根据 stage 和 skill_info 将内容添加到 ChatMessage.content 数组
|
|
2371
|
+
* @param item Progress 或 OtherTypeAnswer 对象
|
|
2372
|
+
* @param message ChatMessage 对象
|
|
2373
|
+
*/
|
|
2374
|
+
appendSkillOrLLMContentToMessage(e, s) {
|
|
2375
|
+
var n, o, a;
|
|
2376
|
+
if (e.stage === "skill") {
|
|
2377
|
+
const i = (n = e.skill_info) == null ? void 0 : n.name;
|
|
2378
|
+
if (i === "zhipu_search_tool") {
|
|
2379
|
+
const d = this.extractWebSearchQueryFromAnswer(e.answer);
|
|
2380
|
+
d && s.content.push({
|
|
2381
|
+
type: T.WEB_SEARCH,
|
|
2382
|
+
content: d
|
|
2383
|
+
});
|
|
2384
|
+
} else if (i === "json2plot") {
|
|
2385
|
+
const d = this.extractChartDataFromArgs((o = e.skill_info) == null ? void 0 : o.args);
|
|
2386
|
+
d && s.content.push({
|
|
2387
|
+
type: T.TEXT,
|
|
2388
|
+
content: `图表数据: ${JSON.stringify(d, null, 2)}`
|
|
2389
|
+
});
|
|
2390
|
+
} else if (i === "execute_code") {
|
|
2391
|
+
const d = this.extractExecuteCodeResult((a = e.skill_info) == null ? void 0 : a.args, e.answer);
|
|
2392
|
+
d && s.content.push({
|
|
2393
|
+
type: T.TOOL,
|
|
2394
|
+
content: {
|
|
2395
|
+
name: "execute_code",
|
|
2396
|
+
title: "代码执行",
|
|
2397
|
+
input: d.input,
|
|
2398
|
+
output: d.output
|
|
2399
|
+
}
|
|
2400
|
+
});
|
|
2401
|
+
} else
|
|
2402
|
+
s.content.push({
|
|
2403
|
+
type: T.TEXT,
|
|
2404
|
+
content: `调用工具: ${i}`
|
|
2405
|
+
});
|
|
2406
|
+
} else e.stage === "llm" && e.answer && s.content.push({
|
|
2407
|
+
type: T.MARKDOWN,
|
|
2408
|
+
content: e.answer
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* 执行 upsert 操作
|
|
2413
|
+
* 将 content 赋值到 JSONPath 指定的位置
|
|
2414
|
+
*/
|
|
2415
|
+
applyUpsert(e, s, n) {
|
|
2416
|
+
if (s.length === 0) return e;
|
|
2417
|
+
const o = { ...e };
|
|
2418
|
+
return this.setNestedProperty(o, s, n), o;
|
|
2419
|
+
}
|
|
2420
|
+
/**
|
|
2421
|
+
* 执行 append 操作
|
|
2422
|
+
* 如果 JSONPath 是数组下标,在该位置插入新对象
|
|
2423
|
+
* 否则在文本后追加内容
|
|
2424
|
+
*/
|
|
2425
|
+
applyAppend(e, s, n) {
|
|
2426
|
+
if (s.length === 0) return e;
|
|
2427
|
+
const o = { ...e }, a = s[s.length - 1];
|
|
2428
|
+
if (typeof a == "number") {
|
|
2429
|
+
const i = s.slice(0, -1), d = this.getNestedProperty(o, i);
|
|
2430
|
+
Array.isArray(d) && (d[a] = n);
|
|
2431
|
+
} else {
|
|
2432
|
+
const i = this.getNestedProperty(o, s);
|
|
2433
|
+
typeof i == "string" && typeof n == "string" ? this.setNestedProperty(o, s, i + n) : this.setNestedProperty(o, s, n);
|
|
2434
|
+
}
|
|
2435
|
+
return o;
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* 获取嵌套属性
|
|
2439
|
+
*/
|
|
2440
|
+
getNestedProperty(e, s) {
|
|
2441
|
+
let n = e;
|
|
2442
|
+
for (const o of s) {
|
|
2443
|
+
if (n == null) return;
|
|
2444
|
+
n = n[o];
|
|
2445
|
+
}
|
|
2446
|
+
return n;
|
|
2447
|
+
}
|
|
2448
|
+
/**
|
|
2449
|
+
* 设置嵌套属性
|
|
2450
|
+
*/
|
|
2451
|
+
setNestedProperty(e, s, n) {
|
|
2452
|
+
if (s.length === 0) return;
|
|
2453
|
+
let o = e;
|
|
2454
|
+
for (let i = 0; i < s.length - 1; i++) {
|
|
2455
|
+
const d = s[i], u = s[i + 1];
|
|
2456
|
+
o[d] == null && (o[d] = typeof u == "number" ? [] : {}), o = o[d];
|
|
2457
|
+
}
|
|
2458
|
+
const a = s[s.length - 1];
|
|
2459
|
+
o[a] = n;
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* 检查是否需要刷新 token
|
|
2463
|
+
* AISHU DIP 平台返回 401 状态码时表示 token 失效
|
|
2464
|
+
* @param status HTTP 状态码
|
|
2465
|
+
* @param error 错误响应体
|
|
2466
|
+
* @returns 返回是否需要刷新 token
|
|
2467
|
+
*/
|
|
2468
|
+
shouldRefreshToken(e, s) {
|
|
2469
|
+
return e === 401;
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* 终止会话
|
|
2473
|
+
* 调用 DIP 的 /app/{agent_id}/chat/termination 接口终止指定会话
|
|
2474
|
+
* @param conversationId 要终止的会话 ID
|
|
2475
|
+
* @returns 返回 Promise,成功时 resolve,失败时 reject
|
|
2476
|
+
*/
|
|
2477
|
+
async terminateConversation(e) {
|
|
2478
|
+
const s = `${this.dipBaseUrl}/app/${this.dipId}/chat/termination`, n = {
|
|
2479
|
+
"Content-Type": "application/json"
|
|
2480
|
+
};
|
|
2481
|
+
this.dipToken && (n.Authorization = this.dipToken.startsWith("Bearer ") ? this.dipToken : `Bearer ${this.dipToken}`);
|
|
2482
|
+
const o = JSON.stringify({
|
|
2483
|
+
conversation_id: e
|
|
2484
|
+
}), a = await fetch(s, {
|
|
2485
|
+
method: "POST",
|
|
2486
|
+
headers: n,
|
|
2487
|
+
body: o
|
|
2488
|
+
});
|
|
2489
|
+
if (!a.ok) {
|
|
2490
|
+
const i = await a.text();
|
|
2491
|
+
throw new Error(`终止会话失败: ${a.status} ${i}`);
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* 执行 API 调用,并在需要时自动刷新 token 并重试一次
|
|
2496
|
+
* @param apiCall API 调用函数
|
|
2497
|
+
* @returns API 调用结果
|
|
2498
|
+
*/
|
|
2499
|
+
async executeDataAgentWithTokenRefresh(e) {
|
|
2500
|
+
var s, n, o, a;
|
|
2501
|
+
try {
|
|
2502
|
+
return await e();
|
|
2503
|
+
} catch (i) {
|
|
2504
|
+
const d = i.status || ((s = i.response) == null ? void 0 : s.status) || 0, u = i.body || ((n = i.response) == null ? void 0 : n.data) || i;
|
|
2505
|
+
if (this.shouldRefreshToken(d, u) && this.dipRefreshToken) {
|
|
2506
|
+
console.log("检测到 DIP token 失效,正在刷新 token...");
|
|
2507
|
+
try {
|
|
2508
|
+
const f = await this.dipRefreshToken();
|
|
2509
|
+
this.dipToken = f, console.log("DIP Token 刷新成功,正在重试请求...");
|
|
2510
|
+
try {
|
|
2511
|
+
return await e();
|
|
2512
|
+
} catch (m) {
|
|
2513
|
+
const y = m.status || ((o = m.response) == null ? void 0 : o.status) || 0, b = m.body || ((a = m.response) == null ? void 0 : a.data) || m;
|
|
2514
|
+
throw this.shouldRefreshToken(y, b) && console.error("重试后仍然提示 token 失效,放弃重试"), m;
|
|
2515
|
+
}
|
|
2516
|
+
} catch (f) {
|
|
2517
|
+
throw console.error("刷新 DIP token 失败:", f), i;
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
throw i;
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
/**
|
|
2524
|
+
* 获取历史会话列表
|
|
2525
|
+
* 调用 DIP 的 GET /app/{agent_id}/conversation 接口获取会话列表
|
|
2526
|
+
* API 端点: GET /app/{agent_id}/conversation?page={page}&size={size}
|
|
2527
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2528
|
+
* @param page 分页页码,默认为 1
|
|
2529
|
+
* @param size 每页返回条数,默认为 10
|
|
2530
|
+
* @returns 返回历史会话列表
|
|
2531
|
+
*/
|
|
2532
|
+
async getConversations(e = 1, s = 10) {
|
|
2533
|
+
var n;
|
|
2534
|
+
try {
|
|
2535
|
+
console.log("正在获取历史会话列表...");
|
|
2536
|
+
const o = `${this.dipBaseUrl}/app/${this.dipId}/conversation?page=${e}&size=${s}`, a = await this.executeDataAgentWithTokenRefresh(async () => {
|
|
2537
|
+
const u = await fetch(o, {
|
|
2538
|
+
method: "GET",
|
|
2539
|
+
headers: {
|
|
2540
|
+
"Content-Type": "application/json",
|
|
2541
|
+
Authorization: `Bearer ${this.dipToken}`
|
|
2542
|
+
}
|
|
2543
|
+
});
|
|
2544
|
+
if (!u.ok) {
|
|
2545
|
+
const x = await u.text(), f = new Error(`获取历史会话列表失败: ${u.status} - ${x}`);
|
|
2546
|
+
throw f.status = u.status, f.body = x, f;
|
|
2547
|
+
}
|
|
2548
|
+
return await u.json();
|
|
2549
|
+
}), d = (((n = a.data) == null ? void 0 : n.entries) || a.entries || []).map((u) => ({
|
|
2550
|
+
conversationID: u.id || "",
|
|
2551
|
+
title: u.title || "未命名会话",
|
|
2552
|
+
created_at: u.create_time || 0,
|
|
2553
|
+
updated_at: u.update_time || 0,
|
|
2554
|
+
message_index: u.message_index,
|
|
2555
|
+
read_message_index: u.read_message_index
|
|
2556
|
+
}));
|
|
2557
|
+
return console.log(`成功获取 ${d.length} 条历史会话`), d;
|
|
2558
|
+
} catch (o) {
|
|
2559
|
+
return console.error("获取历史会话列表失败:", o), [];
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
/**
|
|
2563
|
+
* 获取指定会话 ID 的对话消息列表
|
|
2564
|
+
* 调用 DIP 的 GET /app/{agent_id}/conversation/{conversation_id} 接口获取会话详情
|
|
2565
|
+
* 如果对话消息是 AI 助手消息,则需要调用 reduceAssistantMessage() 解析消息
|
|
2566
|
+
* API 端点: GET /app/{agent_id}/conversation/{conversation_id}
|
|
2567
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2568
|
+
* @param conversationId 会话 ID
|
|
2569
|
+
* @returns 返回对话消息列表
|
|
2570
|
+
*/
|
|
2571
|
+
async getConversationMessages(e) {
|
|
2572
|
+
var s, n;
|
|
2573
|
+
try {
|
|
2574
|
+
console.log("正在获取会话消息列表,conversationId:", e);
|
|
2575
|
+
const o = `${this.dipBaseUrl}/app/${this.dipId}/conversation/${e}`, a = await this.executeDataAgentWithTokenRefresh(async () => {
|
|
2576
|
+
const u = await fetch(o, {
|
|
2577
|
+
method: "GET",
|
|
2578
|
+
headers: {
|
|
2579
|
+
"Content-Type": "application/json",
|
|
2580
|
+
Authorization: `Bearer ${this.dipToken}`
|
|
2581
|
+
}
|
|
2582
|
+
});
|
|
2583
|
+
if (!u.ok) {
|
|
2584
|
+
const x = await u.text(), f = new Error(`获取会话消息列表失败: ${u.status} - ${x}`);
|
|
2585
|
+
throw f.status = u.status, f.body = x, f;
|
|
2586
|
+
}
|
|
2587
|
+
return await u.json();
|
|
2588
|
+
}), i = ((s = a.data) == null ? void 0 : s.Messages) || a.Messages || [], d = [];
|
|
2589
|
+
for (const u of i) {
|
|
2590
|
+
const x = u.id || `msg-${Date.now()}-${Math.random()}`, f = u.origin || "user";
|
|
2591
|
+
if (f === "user") {
|
|
2592
|
+
const m = {
|
|
2593
|
+
messageId: x,
|
|
2594
|
+
role: {
|
|
2595
|
+
name: "用户",
|
|
2596
|
+
type: P.USER,
|
|
2597
|
+
avatar: ""
|
|
2598
|
+
},
|
|
2599
|
+
content: []
|
|
2600
|
+
};
|
|
2601
|
+
try {
|
|
2602
|
+
const y = typeof u.content == "string" ? JSON.parse(u.content) : u.content, b = (y == null ? void 0 : y.text) || "";
|
|
2603
|
+
b && m.content.push({
|
|
2604
|
+
type: T.TEXT,
|
|
2605
|
+
content: b
|
|
2606
|
+
});
|
|
2607
|
+
} catch (y) {
|
|
2608
|
+
console.error("解析用户消息内容失败:", y);
|
|
2609
|
+
}
|
|
2610
|
+
d.push(m);
|
|
2611
|
+
} else if (f === "assistant")
|
|
2612
|
+
try {
|
|
2613
|
+
const m = typeof u.content == "string" ? JSON.parse(u.content) : u.content, y = {
|
|
2614
|
+
messageId: x,
|
|
2615
|
+
role: {
|
|
2616
|
+
name: "AI 助手",
|
|
2617
|
+
type: P.ASSISTANT,
|
|
2618
|
+
avatar: ""
|
|
2619
|
+
},
|
|
2620
|
+
content: []
|
|
2621
|
+
}, b = m == null ? void 0 : m.middle_answer;
|
|
2622
|
+
if (b != null && b.progress && Array.isArray(b.progress))
|
|
2623
|
+
for (const Z of b.progress)
|
|
2624
|
+
this.appendSkillOrLLMContentToMessage(Z, y);
|
|
2625
|
+
const N = m == null ? void 0 : m.final_answer, D = (n = N == null ? void 0 : N.answer) == null ? void 0 : n.text;
|
|
2626
|
+
D && y.content.push({
|
|
2627
|
+
type: T.MARKDOWN,
|
|
2628
|
+
content: D
|
|
2629
|
+
});
|
|
2630
|
+
const R = N == null ? void 0 : N.answer_type_other;
|
|
2631
|
+
R && this.appendSkillOrLLMContentToMessage(R, y), d.push(y);
|
|
2632
|
+
} catch (m) {
|
|
2633
|
+
console.error("解析 AI 助手消息失败:", m);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
return console.log(`成功获取 ${d.length} 条对话消息`), d;
|
|
2637
|
+
} catch (o) {
|
|
2638
|
+
return console.error("获取会话消息列表失败:", o), [];
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
/**
|
|
2642
|
+
* 删除指定 ID 的会话
|
|
2643
|
+
* 调用 DIP 的 DELETE /app/{agent_id}/conversation/{conversation_id} 接口删除会话
|
|
2644
|
+
* API 端点: DELETE /app/{agent_id}/conversation/{conversation_id}
|
|
2645
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2646
|
+
* @param conversationID 会话 ID
|
|
2647
|
+
* @returns 返回 Promise,成功时 resolve,失败时 reject
|
|
2648
|
+
*/
|
|
2649
|
+
async deleteConversation(e) {
|
|
2650
|
+
try {
|
|
2651
|
+
console.log("正在删除会话,conversationID:", e);
|
|
2652
|
+
const s = `${this.dipBaseUrl}/app/${this.dipId}/conversation/${e}`;
|
|
2653
|
+
await this.executeDataAgentWithTokenRefresh(async () => {
|
|
2654
|
+
const n = await fetch(s, {
|
|
2655
|
+
method: "DELETE",
|
|
2656
|
+
headers: {
|
|
2657
|
+
"Content-Type": "application/json",
|
|
2658
|
+
Authorization: `Bearer ${this.dipToken}`
|
|
2659
|
+
}
|
|
2660
|
+
});
|
|
2661
|
+
if (!n.ok && n.status !== 204) {
|
|
2662
|
+
const o = await n.text(), a = new Error(`删除会话失败: ${n.status} - ${o}`);
|
|
2663
|
+
throw a.status = n.status, a.body = o, a;
|
|
2664
|
+
}
|
|
2665
|
+
return n;
|
|
2666
|
+
}), console.log("会话删除成功");
|
|
2667
|
+
} catch (s) {
|
|
2668
|
+
throw console.error("删除会话失败:", s), s;
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
class nr extends Ke(Lt) {
|
|
2674
|
+
// 所有方法都已在 DIPBaseMixin 中实现
|
|
2675
|
+
// 如果需要自定义行为,可以在此覆盖相应方法
|
|
2676
|
+
}
|
|
2677
|
+
class or extends Ke(Ht) {
|
|
2678
|
+
// 所有方法都已在 DIPBaseMixin 中实现
|
|
2679
|
+
// 如果需要自定义行为,可以在此覆盖相应方法
|
|
2680
|
+
}
|
|
2681
|
+
class ar extends le {
|
|
2682
|
+
constructor(l) {
|
|
2683
|
+
super(l);
|
|
2684
|
+
/** 扣子 Bot ID */
|
|
2685
|
+
S(this, "botId");
|
|
2686
|
+
/** 扣子 API Token */
|
|
2687
|
+
S(this, "apiToken");
|
|
2688
|
+
/** 扣子 API 基础 URL */
|
|
2689
|
+
S(this, "baseUrl");
|
|
2690
|
+
/** 用户 ID */
|
|
2691
|
+
S(this, "userId");
|
|
2692
|
+
this.botId = l.botId, this.apiToken = l.apiToken, this.baseUrl = l.baseUrl || "https://api.coze.cn", this.userId = l.userId || "chatkit-user";
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* 获取开场白和预置问题
|
|
2696
|
+
* 调用扣子 API 获取智能体配置信息,提取开场白和预置问题
|
|
2697
|
+
* API 端点: GET /v1/bots/{bot_id}
|
|
2698
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2699
|
+
* @returns 返回开场白信息,包含开场白文案和预置问题
|
|
2700
|
+
*/
|
|
2701
|
+
async getOnboardingInfo() {
|
|
2702
|
+
try {
|
|
2703
|
+
console.log("正在获取扣子智能体配置...");
|
|
2704
|
+
const l = await fetch(`${this.baseUrl}/v1/bots/${encodeURIComponent(this.botId)}?is_published=true`, {
|
|
2705
|
+
method: "GET",
|
|
2706
|
+
headers: {
|
|
2707
|
+
Authorization: `Bearer ${this.apiToken}`,
|
|
2708
|
+
"Content-Type": "application/json"
|
|
2709
|
+
}
|
|
2710
|
+
});
|
|
2711
|
+
if (!l.ok) {
|
|
2712
|
+
const a = await l.text();
|
|
2713
|
+
throw new Error(`获取扣子智能体配置失败: ${l.status} - ${a}`);
|
|
2714
|
+
}
|
|
2715
|
+
const e = await l.json();
|
|
2716
|
+
console.log("扣子智能体配置响应:", e);
|
|
2717
|
+
const n = (e.data || {}).onboarding_info || {}, o = {
|
|
2718
|
+
prologue: n.prologue || "你好!我是 AI 助手,有什么可以帮你的吗?",
|
|
2719
|
+
predefinedQuestions: n.suggested_questions || []
|
|
2720
|
+
};
|
|
2721
|
+
return console.log("开场白信息已提取:", o), o;
|
|
2722
|
+
} catch (l) {
|
|
2723
|
+
return console.error("获取扣子智能体配置失败:", l), {
|
|
2724
|
+
prologue: "你好!我是 AI 助手,有什么可以帮你的吗?",
|
|
2725
|
+
predefinedQuestions: []
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* 创建新的会话
|
|
2731
|
+
* 调用扣子 API 创建新的会话,返回会话 ID
|
|
2732
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2733
|
+
* @returns 返回新创建的会话 ID
|
|
2734
|
+
*/
|
|
2735
|
+
async generateConversation() {
|
|
2736
|
+
var l;
|
|
2737
|
+
try {
|
|
2738
|
+
console.log("正在创建扣子会话...");
|
|
2739
|
+
const e = await fetch(`${this.baseUrl}/v1/conversation/create`, {
|
|
2740
|
+
method: "POST",
|
|
2741
|
+
headers: {
|
|
2742
|
+
"Content-Type": "application/json",
|
|
2743
|
+
Authorization: `Bearer ${this.apiToken}`
|
|
2744
|
+
},
|
|
2745
|
+
body: JSON.stringify({})
|
|
2746
|
+
});
|
|
2747
|
+
if (!e.ok) {
|
|
2748
|
+
const o = await e.text();
|
|
2749
|
+
throw new Error(`创建扣子会话失败: ${e.status} - ${o}`);
|
|
2750
|
+
}
|
|
2751
|
+
const s = await e.json(), n = ((l = s.data) == null ? void 0 : l.id) || s.conversation_id || "";
|
|
2752
|
+
return console.log("扣子会话创建成功, conversationID:", n), n;
|
|
2753
|
+
} catch (e) {
|
|
2754
|
+
return console.error("创建扣子会话失败:", e), "";
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
/**
|
|
2758
|
+
* 向扣子后端发送消息 (流式响应)
|
|
2759
|
+
* 注意:该方法是一个无状态无副作用的函数,不允许修改 state
|
|
2760
|
+
* @param text 发送给后端的用户输入的文本
|
|
2761
|
+
* @param ctx 随用户输入文本一起发送的应用上下文
|
|
2762
|
+
* @param conversationID 发送的对话消息所属的会话 ID
|
|
2763
|
+
* @returns 返回发送的消息结构
|
|
2764
|
+
*/
|
|
2765
|
+
async sendMessage(l, e, s) {
|
|
2766
|
+
var i;
|
|
2767
|
+
let n = l;
|
|
2768
|
+
e && e.title && (n = `【上下文: ${e.title}】
|
|
2769
|
+
${JSON.stringify(e.data, null, 2)}
|
|
2770
|
+
|
|
2771
|
+
${l}`);
|
|
2772
|
+
const o = {
|
|
2773
|
+
bot_id: this.botId,
|
|
2774
|
+
user_id: this.userId,
|
|
2775
|
+
stream: !0,
|
|
2776
|
+
additional_messages: [
|
|
2777
|
+
{
|
|
2778
|
+
role: "user",
|
|
2779
|
+
content: n,
|
|
2780
|
+
content_type: "text"
|
|
2781
|
+
}
|
|
2782
|
+
]
|
|
2783
|
+
};
|
|
2784
|
+
let a = `${this.baseUrl}/v3/chat`;
|
|
2785
|
+
s && (a += `?conversation_id=${encodeURIComponent(s)}`);
|
|
2786
|
+
try {
|
|
2787
|
+
console.log("发起流式 Chat 请求:", { url: a, body: o });
|
|
2788
|
+
const d = await fetch(a, {
|
|
2789
|
+
method: "POST",
|
|
2790
|
+
headers: {
|
|
2791
|
+
"Content-Type": "application/json",
|
|
2792
|
+
Authorization: `Bearer ${this.apiToken}`
|
|
2793
|
+
},
|
|
2794
|
+
body: JSON.stringify(o)
|
|
2795
|
+
});
|
|
2796
|
+
if (!d.ok) {
|
|
2797
|
+
const y = await d.text();
|
|
2798
|
+
throw new Error(`扣子流式 API 调用失败: ${d.status} - ${y}`);
|
|
2799
|
+
}
|
|
2800
|
+
const u = `assistant-${Date.now()}`, x = {
|
|
2801
|
+
messageId: u,
|
|
2802
|
+
content: [],
|
|
2803
|
+
// 初始化为空数组,后续会通过 append*Block 方法添加内容块
|
|
2804
|
+
role: {
|
|
2805
|
+
name: "AI 助手",
|
|
2806
|
+
type: P.ASSISTANT,
|
|
2807
|
+
avatar: ""
|
|
2808
|
+
}
|
|
2809
|
+
};
|
|
2810
|
+
this.setState((y) => ({
|
|
2811
|
+
messages: [...y.messages, x],
|
|
2812
|
+
streamingMessageId: u
|
|
2813
|
+
}));
|
|
2814
|
+
const f = (i = d.body) == null ? void 0 : i.getReader();
|
|
2815
|
+
if (!f)
|
|
2816
|
+
throw new Error("无法获取响应流");
|
|
2817
|
+
return await this.handleStreamResponse(f, u), this.state.messages.find((y) => y.messageId === u) || x;
|
|
2818
|
+
} catch (d) {
|
|
2819
|
+
throw console.error("调用扣子流式 API 失败:", d), d;
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
/**
|
|
2823
|
+
* 将 API 接口返回的 EventStream 增量解析成完整的 AssistantMessage 对象
|
|
2824
|
+
* 对于 Coze,AssistantMessage 就是累积的文本字符串
|
|
2825
|
+
* @param eventMessage 接收到的一条 Event Message
|
|
2826
|
+
* @param prev 上一次增量更新后的文本 buffer
|
|
2827
|
+
* @returns 返回更新后的文本 buffer
|
|
2828
|
+
*/
|
|
2829
|
+
reduceAssistantMessage(l, e, s) {
|
|
2830
|
+
try {
|
|
2831
|
+
const n = l, o = JSON.parse(n.data), a = e;
|
|
2832
|
+
if (console.log("reduceAssistantMessage 调用:", {
|
|
2833
|
+
event: n.event,
|
|
2834
|
+
prevBuffer: a,
|
|
2835
|
+
data: o
|
|
2836
|
+
}), o.conversation_id && o.conversation_id !== this.state.conversationID && this.setState({ conversationID: o.conversation_id }), n.event === "conversation.message.delta") {
|
|
2837
|
+
if (o.content && o.type === "answer") {
|
|
2838
|
+
const i = a + o.content;
|
|
2839
|
+
return console.log("增量内容:", o.content, "新buffer:", i), this.appendMarkdownBlock(s, i), i;
|
|
2840
|
+
}
|
|
2841
|
+
} else if (n.event === "conversation.message.completed") {
|
|
2842
|
+
if (o.content && o.type === "answer")
|
|
2843
|
+
return console.log("消息完成,完整内容:", o.content), this.appendMarkdownBlock(s, o.content), o.content;
|
|
2844
|
+
if (o.type === "verbose")
|
|
2845
|
+
return console.log("忽略 verbose 类型消息"), a;
|
|
2846
|
+
} else {
|
|
2847
|
+
if (n.event === "conversation.chat.completed")
|
|
2848
|
+
return console.log("Chat完成"), a;
|
|
2849
|
+
if (n.event === "conversation.chat.created")
|
|
2850
|
+
return console.log("Chat创建"), a;
|
|
2851
|
+
if (n.event === "conversation.chat.in_progress")
|
|
2852
|
+
return console.log("Chat进行中"), a;
|
|
2853
|
+
if (n.event === "conversation.message.started")
|
|
2854
|
+
return console.log("消息开始"), a;
|
|
2855
|
+
if (n.event === "done")
|
|
2856
|
+
return console.log("收到done事件"), a;
|
|
2857
|
+
}
|
|
2858
|
+
return o.msg_type === "generate_answer_finish" ? (console.log("答案生成完成"), a) : o.status === "completed" ? (console.log("检测到Chat完成状态"), a) : (console.log("未知事件类型,保持原buffer:", n.event, o), a);
|
|
2859
|
+
} catch (n) {
|
|
2860
|
+
return console.error("解析扣子事件失败:", n), e;
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* 检查是否需要刷新 token
|
|
2865
|
+
* Coze 平台返回 401 状态码时表示 token 失效
|
|
2866
|
+
* @param status HTTP 状态码
|
|
2867
|
+
* @param error 错误响应体
|
|
2868
|
+
* @returns 返回是否需要刷新 token
|
|
2869
|
+
*/
|
|
2870
|
+
shouldRefreshToken(l, e) {
|
|
2871
|
+
return l === 401;
|
|
2872
|
+
}
|
|
2873
|
+
/**
|
|
2874
|
+
* 终止会话
|
|
2875
|
+
* Coze 平台目前不支持主动终止会话,此方法为空实现
|
|
2876
|
+
* @param conversationId 要终止的会话 ID
|
|
2877
|
+
* @returns 返回 Promise,直接 resolve
|
|
2878
|
+
*/
|
|
2879
|
+
async terminateConversation(l) {
|
|
2880
|
+
console.warn("Coze 平台不支持主动终止会话功能");
|
|
2881
|
+
}
|
|
2882
|
+
/**
|
|
2883
|
+
* 获取历史会话列表 (Coze 暂不支持)
|
|
2884
|
+
* @param _page 分页页码
|
|
2885
|
+
* @param _size 每页返回条数
|
|
2886
|
+
* @returns 返回空数组
|
|
2887
|
+
*/
|
|
2888
|
+
async getConversations(l, e) {
|
|
2889
|
+
return console.warn("Coze 平台暂不支持获取历史会话列表功能"), [];
|
|
2890
|
+
}
|
|
2891
|
+
/**
|
|
2892
|
+
* 获取指定会话 ID 的对话消息列表 (Coze 暂不支持)
|
|
2893
|
+
* @param _conversationId 会话 ID
|
|
2894
|
+
* @returns 返回空数组
|
|
2895
|
+
*/
|
|
2896
|
+
async getConversationMessages(l) {
|
|
2897
|
+
return console.warn("Coze 平台暂不支持获取会话消息列表功能"), [];
|
|
2898
|
+
}
|
|
2899
|
+
/**
|
|
2900
|
+
* 删除指定 ID 的会话 (Coze 暂不支持)
|
|
2901
|
+
* @param _conversationID 会话 ID
|
|
2902
|
+
* @returns 返回 Promise,直接 resolve
|
|
2903
|
+
*/
|
|
2904
|
+
async deleteConversation(l) {
|
|
2905
|
+
console.warn("Coze 平台暂不支持删除会话功能");
|
|
2906
|
+
}
|
|
2907
|
+
/**
|
|
2908
|
+
* 渲染 Copilot 模式界面
|
|
2909
|
+
*/
|
|
2910
|
+
render() {
|
|
2911
|
+
if (!this.props.visible)
|
|
2912
|
+
return null;
|
|
2913
|
+
const { title: l = "Copilot", onClose: e } = this.props, { messages: s, textInput: n, applicationContext: o, isSending: a, onboardingInfo: i, isLoadingOnboarding: d, streamingMessageId: u } = this.state, x = s.length === 0, f = u !== null;
|
|
2914
|
+
return /* @__PURE__ */ t.jsxs("div", { className: "flex flex-col h-full w-full bg-white shadow-2xl", children: [
|
|
2915
|
+
/* @__PURE__ */ t.jsx(
|
|
2916
|
+
ze,
|
|
2917
|
+
{
|
|
2918
|
+
title: l,
|
|
2919
|
+
onClose: e,
|
|
2920
|
+
onNewChat: this.createConversation
|
|
2921
|
+
}
|
|
2922
|
+
),
|
|
2923
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex-1 overflow-y-auto", children: x ? d ? (
|
|
2924
|
+
// 加载中,显示加载提示
|
|
2925
|
+
/* @__PURE__ */ t.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ t.jsxs("div", { className: "text-center", children: [
|
|
2926
|
+
/* @__PURE__ */ t.jsx("div", { className: "inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mb-4" }),
|
|
2927
|
+
/* @__PURE__ */ t.jsx("p", { className: "text-sm text-gray-500", children: "正在加载..." })
|
|
2928
|
+
] }) })
|
|
2929
|
+
) : (
|
|
2930
|
+
// 加载完成,显示开场白
|
|
2931
|
+
/* @__PURE__ */ t.jsx(
|
|
2932
|
+
Je,
|
|
2933
|
+
{
|
|
2934
|
+
onQuestionClick: this.handleQuestionClick,
|
|
2935
|
+
prologue: i == null ? void 0 : i.prologue,
|
|
2936
|
+
predefinedQuestions: i == null ? void 0 : i.predefinedQuestions
|
|
2937
|
+
}
|
|
2938
|
+
)
|
|
2939
|
+
) : /* @__PURE__ */ t.jsx(Fe, { messages: s }) }),
|
|
2940
|
+
/* @__PURE__ */ t.jsx(
|
|
2941
|
+
Ue,
|
|
2942
|
+
{
|
|
2943
|
+
value: n,
|
|
2944
|
+
onChange: this.setTextInput,
|
|
2945
|
+
onSend: this.handleSend,
|
|
2946
|
+
context: o,
|
|
2947
|
+
onRemoveContext: this.removeApplicationContext,
|
|
2948
|
+
disabled: a,
|
|
2949
|
+
isStreaming: f,
|
|
2950
|
+
onStop: this.handleStop
|
|
2951
|
+
}
|
|
2952
|
+
)
|
|
2953
|
+
] });
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
export {
|
|
2957
|
+
or as Assistant,
|
|
2958
|
+
Ht as AssistantBase,
|
|
2959
|
+
le as ChatKitBase,
|
|
2960
|
+
ar as ChatKitCoze,
|
|
2961
|
+
Rt as ChatMessageType,
|
|
2962
|
+
nr as Copilot,
|
|
2963
|
+
Lt as CopilotBase,
|
|
2964
|
+
Ke as DIPBaseMixin,
|
|
2965
|
+
P as RoleType
|
|
2966
|
+
};
|