@topthink/chat 1.0.50 → 1.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/es/index.js +121 -47
- package/package.json +3 -3
- package/types/components/action-button.d.ts +12 -0
- package/types/components/message-box/context.d.ts +14 -2
- package/types/components/message-box/index.d.ts +12 -5
- package/types/components/message-box/input-box/index.d.ts +3 -7
- package/types/components/message-box/input-box/mic-button.d.ts +0 -1
- package/types/components/message-box/input-box/toolbar/history.d.ts +2 -0
- package/types/components/message-box/input-box/toolbar/index.d.ts +6 -0
- package/types/components/message-box/input-box/toolbar/reset.d.ts +2 -0
- package/types/components/message-box/input-box/use-chat.d.ts +11 -0
- package/types/components/message-box/message-item.d.ts +0 -1
- package/types/components/message-box/speech-action.d.ts +1 -2
- package/types/index.d.ts +1 -1
- package/types/speech/recognition/custom.d.ts +4 -1
- package/types/speech/synthesis/custom.d.ts +7 -1
- package/types/speech/use-recognition.d.ts +3 -3
- package/types/speech/use-synthesis.d.ts +3 -4
- package/types/types.d.ts +3 -1
- package/types/hooks/use-chat.d.ts +0 -30
package/es/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import{Lightbox as n,styled as i,Clipboard as o,css as a,formatSize as s,Tooltip as l,useAsync as c,isImageUrl as d,isRequestError as h,Form as u,Toast as m,InfiniteScroller as p,Offcanvas as g,dayjs as f,RequestButton as b,useImmer as v,request as x}from"@topthink/components";import*as y from"react";import{memo as w,useMemo as k,useRef as E,createContext as j,useContext as N,useState as C,Fragment as M,forwardRef as q,useEffect as z,useCallback as $,useImperativeHandle as S}from"react";import A from"react-markdown";import"katex/dist/katex.min.css";import F from"remark-math";import R from"remark-breaks";import D from"remark-gfm";import I from"rehype-katex";import T from"rehype-highlight";import{codes as P,types as L}from"micromark-util-symbol";import{markdownLineEnding as B}from"micromark-util-character";import O from"lodash/isEqual";import{Spinner as _,OverlayTrigger as U,Popover as H,Badge as K,CloseButton as Q}from"react-bootstrap";import*as W from"path";import X from"path";import J from"eventemitter3";import{createPortal as V}from"react-dom";import Y from"react-textarea-autosize";import G from"use-resize-observer";const Z=function(e,t,r){function n(t){return t!==P.leftSquareBracket?(e.exit("citeMarker"),e.enter("citeData"),e.enter(L.chunkString,{contentType:"string"}),i(t)):(e.consume(t),n)}function i(n){return n===P.rightSquareBracket?(e.exit(L.chunkString),e.exit("citeData"),e.enter("citeMarker"),function(n){if(n!==P.rightSquareBracket)return r(n);return e.consume(n),e.exit("citeMarker"),e.exit("cite"),t(n)}(n)):B(n)||n===P.eof||n>57||n<48?r(n):(e.consume(n),i)}return function(t){return t!==P.leftSquareBracket?r(t):(e.enter("cite"),e.enter("citeMarker"),n(t))}},ee=function(){const e=this.data();e.micromarkExtensions.push({text:{[P.leftSquareBracket]:{tokenize:Z}}}),e.fromMarkdownExtensions.push({enter:{cite:function(e){this.enter({type:"cite",data:{hName:"cite",hChildren:[{type:"text",value:""}]}},e)},citeData:function(){this.buffer()}},exit:{cite:function(e){this.exit(e)},citeData:function(){const e=this.resume();this.stack[this.stack.length-1].data.hChildren[0].value=e}}})},te=n.Image,re={pre:r=>{let{children:n}=r;const i=E(null);return t(se,{ref:i,children:[e(ae,{tooltip:!1,content:()=>{const e=i.current?.getElementsByTagName("code");return e?.[0]?.innerText||""}}),n]})},a:t=>{let{node:r,href:n,...i}=t;const o=n?.startsWith("http")?"_blank":"_self";return e("a",{...i,href:n,target:o})},img:t=>{let{node:r,...n}=t;return e(te,{...n})}},ne=[[F,{singleDollarTextMath:!1}],D,R],ie=[I,[T,{detect:!1,ignoreMissing:!0}]],oe=w((t=>{let{content:r,components:n,cite:i}=t;r=r.replace(/\\\(\s(.+?)\s\\\)/g,"$$$$ $1 $$$$");const o=k((()=>{const e={...re,...n};return i&&(e.cite=i),e}),[n,i]),a=k((()=>i?[...ne,ee]:ne),[i]);return e(le,{remarkPlugins:a,rehypePlugins:ie,components:o,children:r})}),O),ae=i(o)`
|
|
2
2
|
position: absolute;
|
|
3
3
|
right: 10px;
|
|
4
4
|
top: 1em;
|
|
@@ -18,17 +18,17 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
18
18
|
&:hover {
|
|
19
19
|
opacity: 1;
|
|
20
20
|
}
|
|
21
|
-
`,
|
|
21
|
+
`,se=i.pre`
|
|
22
22
|
position: relative;
|
|
23
23
|
|
|
24
24
|
&:hover {
|
|
25
|
-
${
|
|
25
|
+
${ae} {
|
|
26
26
|
pointer-events: all;
|
|
27
27
|
transform: translateX(0px);
|
|
28
28
|
opacity: 0.5;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
`,
|
|
31
|
+
`,le=i(A)`
|
|
32
32
|
-ms-text-size-adjust: 100%;
|
|
33
33
|
-webkit-text-size-adjust: 100%;
|
|
34
34
|
line-height: 1.8;
|
|
@@ -298,7 +298,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
298
298
|
.hljs-strong {
|
|
299
299
|
font-weight: 700;
|
|
300
300
|
}
|
|
301
|
-
`,
|
|
301
|
+
`,ce=j(null);function de(){const e=N(ce);if(!e)throw new Error("useContext must be used within a Provider");return e}function he(t){let{children:r,...n}=t;return e(ce.Provider,{value:n,children:r})}const ue=n.Image;function me(t){let{src:r,...n}=t;const{imageResolver:i}=de();return i&&r&&(r=i(r)),e(pe,{children:e(ue,{src:r,...n})})}const pe=i.div`
|
|
302
302
|
margin-bottom: .5rem;
|
|
303
303
|
margin-top: .5rem;
|
|
304
304
|
border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
|
|
@@ -323,9 +323,9 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
323
323
|
max-height: 100%;
|
|
324
324
|
max-width: 100%;
|
|
325
325
|
}
|
|
326
|
-
`;function
|
|
326
|
+
`;function ge(r){let{tool:n}=r;const[i,o]=C(!1),{logLevel:a="none"}=de();let s=null;n.content&&("string"==typeof n.content?s=e(oe,{content:n.content}):"image"===n.content.type&&(s=e(me,{src:n.content.image})));const l="response"in n;return t(M,{children:["stats"==a&&e("div",{className:"mb-2",children:t("div",{role:"button",className:"d-inline-flex align-items-center shadow-sm rounded bg-white p-1 px-2 fs-7 gap-2",children:[l?n.error?e("i",{className:"bi bi-x-circle-fill text-danger"}):e("i",{className:"bi bi-check-circle-fill text-success"}):e(_,{animation:"border",variant:"primary",size:"sm"}),e("span",{className:"text-muted",children:l?"已使用":"正在使用"}),e("span",{children:n.title})]})}),"all"==a&&e("div",{className:"mb-2",children:t("div",i&&l?{className:"shadow-sm rounded bg-white fs-7",children:[t("div",{onClick:()=>o(!1),role:"button",className:"d-flex align-items-center p-1 px-2 gap-2",children:[n.error?e("i",{className:"bi bi-x-circle-fill text-danger"}):e("i",{className:"bi bi-check-circle-fill text-success"}),e("span",{className:"text-muted",children:"已使用"}),e("span",{children:n.title}),e("i",{className:"bi bi-caret-up-fill text-muted"})]}),t("div",{className:"border-top p-2 d-flex flex-column gap-2",children:[t("div",{className:"border rounded bg-light",children:[e("div",{className:"d-flex align-items-center p-1 px-2 fs-7 gap-2",children:e("span",{className:"text-muted",children:"参数"})}),e("div",{className:"border-top p-2 overflow-hidden",children:n.arguments})]}),t("div",{className:"border rounded bg-light",children:[e("div",{className:"d-flex align-items-center p-1 px-2 fs-7 gap-2",children:e("span",{className:"text-muted",children:"响应"})}),e(fe,{className:"border-top p-2 overflow-hidden",children:n.response||"None"})]})]})]}:{onClick:()=>o(l),role:"button",className:"d-inline-flex align-items-center shadow-sm rounded bg-white p-1 px-2 fs-7 gap-2",children:[l?n.error?e("i",{className:"bi bi-x-circle-fill text-danger"}):e("i",{className:"bi bi-check-circle-fill text-success"}):e(_,{animation:"border",variant:"primary",size:"sm"}),e("span",{className:"text-muted",children:l?"已使用":"正在使用"}),e("span",{children:n.title}),l&&e("i",{className:"bi bi-caret-down-fill text-muted"})]})}),s]})}const fe=i.div`
|
|
327
327
|
white-space: pre-wrap;
|
|
328
|
-
`;var
|
|
328
|
+
`;var be,ve,xe;function ye(){return ye=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},ye.apply(this,arguments)}const we=e=>y.createElement("svg",ye({xmlns:"http://www.w3.org/2000/svg",width:20,height:10,fill:"#fff",viewBox:"0 0 120 30"},e),be||(be=y.createElement("circle",{cx:15,cy:15,r:15,fill:"#3c60ff"},y.createElement("animate",{attributeName:"r",begin:"0s",calcMode:"linear",dur:"0.8s",from:15,repeatCount:"indefinite",to:15,values:"15;9;15"}),y.createElement("animate",{attributeName:"fill-opacity",begin:"0s",calcMode:"linear",dur:"0.8s",from:1,repeatCount:"indefinite",to:1,values:"1;.5;1"}))),ve||(ve=y.createElement("circle",{cx:60,cy:15,r:9,fill:"#3c60ff",fillOpacity:.3},y.createElement("animate",{attributeName:"r",begin:"0s",calcMode:"linear",dur:"0.8s",from:9,repeatCount:"indefinite",to:9,values:"9;15;9"}),y.createElement("animate",{attributeName:"fill-opacity",begin:"0s",calcMode:"linear",dur:"0.8s",from:.5,repeatCount:"indefinite",to:.5,values:".5;1;.5"}))),xe||(xe=y.createElement("circle",{cx:105,cy:15,r:15,fill:"#3c60ff"},y.createElement("animate",{attributeName:"r",begin:"0s",calcMode:"linear",dur:"0.8s",from:15,repeatCount:"indefinite",to:15,values:"15;9;15"}),y.createElement("animate",{attributeName:"fill-opacity",begin:"0s",calcMode:"linear",dur:"0.8s",from:1,repeatCount:"indefinite",to:1,values:"1;.5;1"}))));const ke=function(t){let{ext:r}=t;const{result:n}=c((async e=>(await function(e){switch(e){case"../../images/file/docx.svg":return import("./docx-nWXnlyT_.js");case"../../images/file/jpg.svg":return import("./jpg-6tBxSzWk.js");case"../../images/file/md.svg":return import("./md-GZ3HJPcw.js");case"../../images/file/pdf.svg":return import("./pdf-pVX1_E6T.js");case"../../images/file/png.svg":return import("./png-u0o1NMqQ.js");case"../../images/file/pptx.svg":return import("./pptx-Hprz0cON.js");case"../../images/file/txt.svg":return import("./txt-eHeCpvNO.js");case"../../images/file/xlsx.svg":return import("./xlsx-uOft-SV2.js");default:return new Promise((function(t,r){("function"==typeof queueMicrotask?queueMicrotask:setTimeout)(r.bind(null,new Error("Unknown variable dynamic import: "+e)))}))}}(`../../images/file/${e}.svg`)).default),[r]);return n?e("img",{width:30,height:30,src:n}):null};function Ee(r){let{className:n,name:i,size:o,loading:a,error:c,onRemove:d}=r;const h=X.extname(i).substring(1),u=t(Me,{className:n,$error:!!c,children:[t(Ce,{children:[e(ke,{ext:h}),a&&e(_,{variant:"primary"})]}),t(Ne,{children:[e("h4",{children:i}),e("p",{children:s(o,1)})]}),d&&e(je,{onClick:e=>{e.preventDefault(),d()},children:e("i",{className:"bi bi-trash3"})})]});return c?e(l,{placement:"top",tooltip:c,children:u}):u}const je=i.div`
|
|
329
329
|
width: 1.75rem;
|
|
330
330
|
height: 1.75rem;
|
|
331
331
|
align-items: center;
|
|
@@ -340,7 +340,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
340
340
|
color: var(--bs-danger);
|
|
341
341
|
background-color: var(--bs-danger-bg-subtle);
|
|
342
342
|
}
|
|
343
|
-
`,
|
|
343
|
+
`,Ne=i.div`
|
|
344
344
|
flex: 1;
|
|
345
345
|
overflow: hidden;
|
|
346
346
|
|
|
@@ -361,7 +361,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
361
361
|
line-height: 20px;
|
|
362
362
|
margin-bottom: 0;
|
|
363
363
|
}
|
|
364
|
-
`,
|
|
364
|
+
`,Ce=i.div`
|
|
365
365
|
position: relative;
|
|
366
366
|
width: 3rem;
|
|
367
367
|
height: 3rem;
|
|
@@ -375,7 +375,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
375
375
|
position: absolute;
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
-
`,
|
|
378
|
+
`,Me=i.div`
|
|
379
379
|
display: flex;
|
|
380
380
|
gap: .5rem;
|
|
381
381
|
padding: .5rem;
|
|
@@ -388,10 +388,10 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
388
388
|
border-color: var(--bs-primary);
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
${e=>e.$error&&
|
|
391
|
+
${e=>e.$error&&a`
|
|
392
392
|
border-color: var(--bs-danger) !important;
|
|
393
393
|
`}
|
|
394
|
-
`;var
|
|
394
|
+
`;var qe=q((function(t,r){let{children:n,tooltip:i,onClick:o,disabled:a,...s}=t;a&&(o=void 0);const c=e(ze,{ref:r,onClick:o,$disabled:a,...s,children:n});return i?e(l,{tooltip:i,placement:"top",children:c}):c}));const ze=i.div`
|
|
395
395
|
align-items: center;
|
|
396
396
|
justify-content: center;
|
|
397
397
|
border-radius: .375rem;
|
|
@@ -406,7 +406,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
406
406
|
height: 1.875rem;
|
|
407
407
|
overflow: hidden;
|
|
408
408
|
|
|
409
|
-
${e=>e.$disabled&&
|
|
409
|
+
${e=>e.$disabled&&a`
|
|
410
410
|
color: var(--bs-gray-400) !important;
|
|
411
411
|
`}
|
|
412
412
|
.bi {
|
|
@@ -416,7 +416,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
416
416
|
line-height: 1.75rem;
|
|
417
417
|
text-align: center;
|
|
418
418
|
|
|
419
|
-
${e=>!e.$disabled&&
|
|
419
|
+
${e=>!e.$disabled&&a`
|
|
420
420
|
&:hover {
|
|
421
421
|
color: var(--bs-dark);
|
|
422
422
|
background-color: var(--bs-gray-200);
|
|
@@ -424,7 +424,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
424
424
|
`}
|
|
425
425
|
|
|
426
426
|
}
|
|
427
|
-
`;let
|
|
427
|
+
`;let $e=class{#e;#t=[];#r=0;constructor(){this.#e=new J}speak(){for(this.#e.emit("playing",!0);this.#r<this.#t.length;){const e=this.#t[this.#r],t=new SpeechSynthesisUtterance(e),r=++this.#r;t.onend=()=>{r>=this.#t.length&&this.clear()},t.onerror=()=>{this.clear()},window.speechSynthesis.speak(t)}}clear(){this.#e.emit("playing",!1)}start(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.#t=Array.isArray(e)?e:[e],t||(window.speechSynthesis.cancel(),this.#r=0),this.speak()}stop(){window.speechSynthesis.cancel(),this.clear()}onPlaying(e){this.#e.on("playing",e)}onSpeaking(e){this.#e.on("speaking",e)}};const Se=new Map;let Ae=class{#n;#e;#t=[];#i=new Map;#o=!1;#r=0;#a=!1;constructor(e){this.#n=e,this.#e=new J}createLoader(e){const t=new Promise((async t=>{try{const{type:r,data:n}=await this.#n(e),i=new Audio(`data:${r};base64,${n}`);this.#i.set(e,i),t(i)}catch{this.#i.delete(e),t(void 0)}}));return this.#i.set(e,t),t}async loadAudioData(){this.#a=!0,this.#e.emit("speaking",!0);let e=0;for(;e<this.#t.length;){const t=this.#t[e];!this.#i.has(t)&&this.#a&&await this.createLoader(t),e++}this.#e.emit("speaking",!1),this.#a=!1}waitForAudioLoaded(e){const t=this.#i.get(e);return t instanceof Promise?t:Promise.resolve(t)}async playAudio(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.#o=!0;const t=await this.waitForAudioLoaded(this.#t[e]);this.#e.emit("playing",!0),t?(Se.set(this,t),t.onpause=async()=>{t.ended?(this.#r++,this.#r<this.#t.length?await this.playAudio(this.#r):this.clear()):this.clear()},await t.play()):this.clear()}clear(){this.#o=!1,this.#a=!1,this.#e.emit("playing",!1),this.#e.emit("speaking",!1),Se.delete(this)}start(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];Se.forEach(((e,t)=>{t!==this&&(e.pause(),e.currentTime=0)})),this.#t=Array.isArray(e)?e:[e],t||(this.#r=0),this.#a||this.loadAudioData(),this.#o||this.playAudio()}update(e){this.#t=Array.isArray(e)?e:[e]}stop(){const e=Se.get(this);e&&(e.pause(),e.currentTime=0)}onPlaying(e){this.#e.on("playing",e)}onSpeaking(e){this.#e.on("speaking",e)}};function Fe(e){let{text:t,loading:r,loader:n}=e;const i=E(),[o,a]=C(!1),[s,l]=C(!1),c=E(r),d=async function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];i.current||(i.current=n?new Ae(n):new $e,i.current.onSpeaking(a),i.current.onPlaying(l));let o="";"string"==typeof t?o=t:t.current&&(o=function(e){const t=e.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li:not(:has(p,h1, h2, h3, h4, h5, h6))");return Array.from(t).flatMap((e=>e.textContent?[e.textContent]:[]))}(t.current),r&&o.pop()),o&&0!==o.length&&i.current.start(o,e)};return z((()=>{if(c.current&&"string"!=typeof t&&t.current){if(r){const e={childList:!0,subtree:!0},r=new MutationObserver((function(){d(!0)}));return r.observe(t.current,e),d(),()=>{r.disconnect()}}d(!0)}}),[r]),z((()=>()=>{i.current&&(i.current.stop(),i.current=void 0)}),[]),{playing:s,speaking:o,start:d,stop:()=>{i.current&&i.current.stop()}}}function Re(r){let{model:n="builtin",voice:i,loading:o,autoplay:a,contentRef:s,avatarRef:l}=r;const{request:c}=de(),d=k((()=>{if("builtin"!==n)return async e=>(await c({url:"/speech",method:"post",data:{model:n,voice:i,input:e}})).audio}),[n,i]),{playing:h,speaking:u,start:m,stop:p}=Fe({loader:d,text:s,loading:a&&o});let g=null;return l.current&&(u&&(g=V(e(De,{children:e(_,{size:"sm",variant:"light"})}),l.current)),h&&(g=V(e(De,{children:e(Ie,{className:"bi bi-volume-down-fill text-light"})}),l.current))),t(qe,{disabled:o&&!h,onClick:()=>{h?p():m()},children:[h?e(Ie,{className:"bi bi-volume-down-fill"}):u?e(_,{size:"sm",variant:"primary"}):e(Ie,{className:"bi bi-volume-down"}),g]})}const De=i.div`
|
|
428
428
|
position: absolute;
|
|
429
429
|
top: 0;
|
|
430
430
|
left: 0;
|
|
@@ -434,12 +434,12 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
434
434
|
align-items: center;
|
|
435
435
|
justify-content: center;
|
|
436
436
|
background-color: rgba(0, 0, 0, .3);
|
|
437
|
-
`,
|
|
437
|
+
`,Ie=i.i`
|
|
438
438
|
|
|
439
439
|
&::before {
|
|
440
440
|
transform: scale(1.4)
|
|
441
441
|
}
|
|
442
|
-
`,
|
|
442
|
+
`,Te=w((n=>{let{message:i,actions:a,updater:s,cite:l,speech:c}=n;const{query:h,quote:u,files:m=[],chunks:p,annotation:g}=i,{user:f,bot:b,logLevel:v="none"}=de(),x=k((()=>p?p.reduce((function(e,t){return e+t.content+"\n"+t.tools.reduce(((e,t)=>t.content&&"string"==typeof t.content?e+t.content+"\n":e),"")}),""):""),[p]),y=E(null),w=E(null),j=E(null);return t(r,{children:[(h||m.length>0)&&t(Xe,{$reverse:!0,children:[f&&e(Ke,{children:e("img",{src:f.avatar})}),e(Qe,{}),t(We,{ref:y,children:[h&&e(oe,{content:h}),u&&e(U,{trigger:"click",container:y,rootClose:!0,placement:"bottom",overlay:e(Pe,{body:!0,children:u}),children:e(Be,{children:e(Le,{children:u})})}),m.length>0&&m.map(((t,r)=>{let{name:n,size:i,path:o}=t;return d(o)?e(me,{src:`/uploads/${o}`},r):e(_e,{children:e(Ee,{name:n,size:i})},r)}))]})]}),p&&t(Xe,{children:[e(Ke,{ref:w,children:e("img",{src:b.avatar})}),e(Qe,{}),t(We,{children:[(h||m.length>0)&&t(Ue,{children:[e(o,{placement:"top",content:x,as:qe,tooltip:!0}),c&&e(Re,{loading:i.loading,avatarRef:w,contentRef:j,...c}),a?.({Component:qe,message:i,content:x,setMessage:s})]}),e(He,{children:["stats","all"].includes(v)&&i.stats&&t(r,{children:[t("span",{children:["耗时 ",i.stats.latency/1e3," 秒"]}),t("span",{children:["花费 Token ",i.stats.usage]})]})}),e(Oe,{ref:j,$deleted:!!g,children:p.length>0&&p.map(((r,n)=>t(M,{children:[r.content&&e(oe,{cite:l,content:r.content}),r.tools.map(((t,r)=>e(ge,{tool:t},r))),r.error&&e(oe,{content:`[${r.error}]`})]},n)))}),g&&t("div",{children:[t("div",{className:"d-flex align-items-center",children:[e("span",{className:"fs-7 text-secondary me-2",children:"标注的答案"}),e("hr",{className:"flex-fill"})]}),e(oe,{content:g.answer})]}),i.loading&&e(we,{})]})]})]})})),Pe=i(H)`
|
|
443
443
|
max-width: calc(100% - .875rem * 2);
|
|
444
444
|
width: calc(100% - .875rem * 2);
|
|
445
445
|
font-size: 1rem;
|
|
@@ -448,25 +448,25 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
448
448
|
.popover-body {
|
|
449
449
|
padding: .5rem .75rem;
|
|
450
450
|
}
|
|
451
|
-
`,
|
|
451
|
+
`,Le=i.div`
|
|
452
452
|
overflow: hidden;
|
|
453
453
|
text-overflow: ellipsis;
|
|
454
454
|
word-break: break-all;
|
|
455
455
|
-webkit-line-clamp: 2;
|
|
456
456
|
-webkit-box-orient: vertical;
|
|
457
457
|
display: -webkit-box;
|
|
458
|
-
`,
|
|
458
|
+
`,Be=i.div`
|
|
459
459
|
padding: .5rem .75rem;
|
|
460
460
|
color: var(--bs-secondary);
|
|
461
461
|
border-radius: var(--bs-border-radius-lg);
|
|
462
462
|
background: #FFFFFF;
|
|
463
463
|
cursor: pointer;
|
|
464
|
-
`,
|
|
465
|
-
${e=>e.$deleted&&
|
|
464
|
+
`,Oe=i.div`
|
|
465
|
+
${e=>e.$deleted&&a`
|
|
466
466
|
text-decoration-line: line-through;
|
|
467
467
|
color: var(--bs-secondary);
|
|
468
468
|
`}
|
|
469
|
-
`,
|
|
469
|
+
`,_e=i.div`
|
|
470
470
|
width: 100%;
|
|
471
471
|
margin-bottom: .5rem;
|
|
472
472
|
margin-top: .5rem;
|
|
@@ -478,7 +478,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
478
478
|
&:last-child {
|
|
479
479
|
margin-bottom: 0;
|
|
480
480
|
}
|
|
481
|
-
`,
|
|
481
|
+
`,Ue=i.div`
|
|
482
482
|
position: absolute;
|
|
483
483
|
top: -1.1rem;
|
|
484
484
|
right: 0;
|
|
@@ -486,7 +486,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
486
486
|
gap: .5rem;
|
|
487
487
|
opacity: 0;
|
|
488
488
|
z-index: 1;
|
|
489
|
-
`,
|
|
489
|
+
`,He=i.div`
|
|
490
490
|
position: absolute;
|
|
491
491
|
bottom: -1.4rem;
|
|
492
492
|
left: 0;
|
|
@@ -499,7 +499,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
499
499
|
display: flex;
|
|
500
500
|
opacity: 0;
|
|
501
501
|
z-index: 1;
|
|
502
|
-
`,
|
|
502
|
+
`,Ke=i.div`
|
|
503
503
|
width: 35px;
|
|
504
504
|
height: 35px;
|
|
505
505
|
border-radius: 50%;
|
|
@@ -510,14 +510,14 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
510
510
|
width: 100%;
|
|
511
511
|
height: 100%;
|
|
512
512
|
}
|
|
513
|
-
`,
|
|
513
|
+
`,Qe=i.div`
|
|
514
514
|
width: 0;
|
|
515
515
|
height: 0;
|
|
516
516
|
content: "";
|
|
517
517
|
border: 5px solid transparent;
|
|
518
518
|
border-right-color: #f3f3f3;
|
|
519
519
|
transform: translateY(10px);
|
|
520
|
-
`,
|
|
520
|
+
`,We=i.div`
|
|
521
521
|
padding: .875rem;
|
|
522
522
|
background-color: rgb(243, 243, 243);
|
|
523
523
|
border-radius: var(--bs-border-radius-lg);
|
|
@@ -525,27 +525,27 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
525
525
|
position: relative;
|
|
526
526
|
|
|
527
527
|
&:hover {
|
|
528
|
-
${
|
|
528
|
+
${He}, ${Ue} {
|
|
529
529
|
opacity: 1;
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
|
-
`,
|
|
532
|
+
`,Xe=i.div`
|
|
533
533
|
display: flex;
|
|
534
534
|
justify-content: flex-start;
|
|
535
535
|
padding: 1rem 0 1rem 0;
|
|
536
|
-
${e=>e.$reverse&&
|
|
536
|
+
${e=>e.$reverse&&a`
|
|
537
537
|
flex-direction: row-reverse;
|
|
538
538
|
|
|
539
|
-
${
|
|
539
|
+
${Qe} {
|
|
540
540
|
border-left-color: rgba(var(--bs-primary-rgb), 0.1);
|
|
541
541
|
border-right-color: transparent;
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
-
${
|
|
544
|
+
${We} {
|
|
545
545
|
background: rgba(var(--bs-primary-rgb), 0.1);
|
|
546
546
|
}
|
|
547
547
|
`};
|
|
548
|
-
`,
|
|
548
|
+
`,Je=[".txt",".md",".pdf",".docx",".xlsx",".pptx",".png",".jpg"];function Ve(t){let{variables:r,values:n,onSubmit:i,onChange:o,children:a}=t;const s={},l=[],c={};return r.forEach((e=>{s[e.key]={type:"string",title:e.label},"textarea"===e.type?c[e.key]={"ui:widget":"textarea"}:"select"===e.type&&e.options&&(s[e.key].enum=e.options,s[e.key].enumNames=e.options,e.options.length>0&&(s[e.key].default=e.options[0])),e.required&&l.push(e.key)})),e(u,{schema:{type:"object",properties:s,required:l},formData:n,omitExtraData:!0,uiSchema:c,submitText:"开始对话",onSubmit:i,onChange:o,children:a})}const Ye=i.button`
|
|
549
549
|
color: var(--bs-secondary);
|
|
550
550
|
cursor: pointer;
|
|
551
551
|
display: flex;
|
|
@@ -568,19 +568,93 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
568
568
|
background-color: var(--bs-gray-200);
|
|
569
569
|
}
|
|
570
570
|
|
|
571
|
-
`;class
|
|
571
|
+
`;class Ge{#s;#e;constructor(){this.#e=new J}onResult(e){this.#e.on("result",e)}onRecording(e){this.#e.on("recording",e)}onTranscribing(e){this.#e.on("transcribing",e)}start(){if(!this.#s){const e=window.SpeechRecognition||window.webkitSpeechRecognition;if(!e)return void m.error("浏览器不支持语音识别");const t=new e;t.continuous=!0,t.lang=navigator.language,t.onresult=e=>{const t=Array.from(e.results).at(-1)?.item(0).transcript;t&&this.#e.emit("result",t)},t.onspeechend=()=>{this.#e.emit("recording",!1)},t.onerror=()=>{this.#e.emit("recording",!1)},this.#s=t}this.#e.emit("recording",!0),this.#s.start()}stop(){this.#s?.stop(),this.#e.emit("recording",!1)}}class Ze{#e;#n;#l;#c;constructor(e){this.#n=e,this.#e=new J}async start(){try{this.#l=await navigator.mediaDevices.getUserMedia({audio:!0}),this.#c=new AudioContext;const e=this.#c.createScriptProcessor(0,1,1);this.#c.createMediaStreamSource(this.#l).connect(e),e.connect(this.#c.destination);let t=[],r=0;const n=.01,i=1;e.onaudioprocess=e=>{const o=e.playbackTime,a=e.inputBuffer.getChannelData(0);let s=!0;for(let e=0;e<a.length;e++)if(Math.abs(a[e])>n){s=!1;break}if(s){const e=o-r;e>i&&(t.length>1&&(this.save(t),t=[]),e>10&&this.stop())}else t.push(new Float32Array(a)),r=o},this.#e.emit("recording",!0)}catch(e){m.error(e.message)}}convertBuffer(e){const t=new Float32Array(e),r=new Int16Array(e.length);for(let e=0;e<t.length;e++){const n=Math.max(-1,Math.min(1,t[e]));r[e]=n<0?32768*n:32767*n}return r}async encodeMP3(e){const{Mp3Encoder:t}=await import("@breezystack/lamejs"),r=new t(1,44100,128),n=[];for(const t of e){const e=this.convertBuffer(t),i=1152;let o=e.length;for(let t=0;o>=0;t+=i){const a=e.subarray(t,t+i),s=r.encodeBuffer(a);n.push(new Int8Array(s)),o-=i}}return n.push(r.flush()),new Blob(n,{type:"audio/mp3"})}async save(e){const t=await this.encodeMP3(e);try{this.#e.emit("transcribing",!0);const e=await this.#n(t);e&&this.#e.emit("result",e)}catch(e){}finally{this.#e.emit("transcribing",!1)}}stop(){this.#l&&(this.#l.getTracks().forEach((e=>e.stop())),this.#l=void 0),this.#c&&(this.#c.close(),this.#c=void 0),this.#e.emit("recording",!1)}onResult(e){this.#e.on("result",e)}onRecording(e){this.#e.on("recording",e)}onTranscribing(e){this.#e.on("transcribing",e)}}const et=q(((r,n)=>{let{onResult:i,model:o="builtin"}=r;const{request:a}=de(),s=k((()=>{if("builtin"!==o)return async e=>{const t=new FormData;t.append("file",e,"audio.mp3"),t.append("model",o);return(await a({url:"/transcriptions",method:"post",data:t})).text}}),[o]),{start:c,stop:d,recording:h,transcribing:u}=function(e){let{onResult:t,loader:r}=e;const n=E(),[i,o]=C(!1),[a,s]=C(!1);return z((()=>()=>{n.current&&(n.current.stop(),n.current=void 0)}),[]),{recording:i,transcribing:a,start:async()=>{n.current||(n.current=r?new Ze(r):new Ge,n.current.onRecording(o),n.current.onTranscribing(s),n.current.onResult(t)),n.current.start()},stop:()=>{n.current&&n.current.stop()}}}({onResult:i,loader:s});return S(n,(()=>({start:c,stop:d})),[c,d]),e(l,{tooltip:h?"停止":"语音输入",placement:"top",children:t(Ye,{onMouseDown:e=>{e.preventDefault(),h?d():c()},children:[u&&e(tt,{animation:"border",variant:"primary",size:"sm"}),e("i",h?{className:"bi bi-mic-fill text-danger"}:{className:"bi bi-mic"})]})})})),tt=i(_)`
|
|
572
572
|
position: absolute;
|
|
573
573
|
--bs-spinner-width: .75rem;
|
|
574
574
|
--bs-spinner-height: .75rem;
|
|
575
575
|
--bs-spinner-border-width: 0.1em;
|
|
576
|
-
|
|
576
|
+
`,rt=q(((t,r)=>{let{className:n,children:i,size:o,tooltip:a,placement:s,onClick:c,onMouseDown:d}=t;const h=e(nt,{ref:r,className:n,onClick:c,onMouseDown:d,$size:o,children:i});return a?e(l,{tooltip:a,placement:s,children:h}):h})),nt=i.div`
|
|
577
|
+
width: 2rem;
|
|
578
|
+
height: 2rem;
|
|
579
|
+
align-items: center;
|
|
580
|
+
justify-content: center;
|
|
581
|
+
border-radius: .375rem;
|
|
582
|
+
cursor: pointer;
|
|
583
|
+
font-size: 1.2rem;
|
|
584
|
+
color: var(--bs-secondary);
|
|
585
|
+
display: flex;
|
|
586
|
+
|
|
587
|
+
svg {
|
|
588
|
+
font-size: 1.5rem;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
${e=>{let{$size:t}=e;return"sm"===t&&a`
|
|
592
|
+
width: 1.5rem;
|
|
593
|
+
height: 1.5rem;
|
|
594
|
+
font-size: 1rem;
|
|
595
|
+
`}};
|
|
596
|
+
|
|
597
|
+
&:hover {
|
|
598
|
+
background-color: var(--bs-secondary-bg-subtle);
|
|
599
|
+
}
|
|
600
|
+
`;function it(){const{request:n,reset:i,conversationId:o}=de(),[a,s]=C(!1);return t(r,{children:[e(rt,{tooltip:"历史记录",placement:"top",onClick:()=>s(!0),children:e("i",{className:"bi bi-clock-history"})}),e(g,{show:a,onHide:()=>{C(!1)},placement:"end",header:"聊天历史记录",bodyAs:ot,children:a&&e(dt,{children:e(ct,{useWindow:!1,source:e=>n({url:"/conversation",params:e}),render:r=>{let{data:a,loading:s,setData:c}=r;return a.length||s?a.map(((r,a)=>{const s=r.messages?.reduce(((e,t)=>e+t.chunks.reduce(((e,t)=>e+(t.content||"")),"")),"");return t(M,{children:[a>0&&e("hr",{className:"mx-2 my-2"}),t(lt,{onClick:()=>{i(r)},children:[t(st,{children:[o===r.id&&e(K,{bg:"secondary",children:"当前"}),e("span",{className:"fw-bold overflow-hidden text-truncate me-auto",children:r.title||"未命名对话"}),e("span",{className:"text-body text-opacity-50 flex-shrink-0 ms-5",children:f(r.update_time).fromNow()})]}),t(at,{children:[e("span",{className:"overflow-hidden text-truncate me-auto",children:s||" "}),e("span",{className:"ms-3",children:o!==r.id&&e(l,{tooltip:"删除",children:e(b,{as:"a",confirm:"确定要删除吗?",onRequest:()=>n({url:`/conversation/${r.id}`,method:"DELETE"}),onSuccess:()=>{c((e=>{const t=e.findIndex((e=>e.id===r.id));-1!==t&&e.splice(t,1)}))},children:e("i",{className:"bi bi-trash3"})})})})]})]})]},r.id)})):e("div",{className:"text-muted text-center py-5",children:"暂无对话记录"})}})})})]})}const ot=i.div`
|
|
601
|
+
padding: 0;
|
|
602
|
+
overflow: hidden;
|
|
603
|
+
`,at=i.div`
|
|
604
|
+
color: var(--bs-gray-600);
|
|
605
|
+
font-weight: 400;
|
|
606
|
+
line-height: 22px;
|
|
607
|
+
display: flex;
|
|
608
|
+
align-items: center;
|
|
609
|
+
|
|
610
|
+
& :last-child {
|
|
611
|
+
display: none;
|
|
612
|
+
}
|
|
613
|
+
`,st=i.div`
|
|
614
|
+
display: flex;
|
|
615
|
+
align-items: center;
|
|
616
|
+
gap: .25rem;
|
|
617
|
+
`,lt=i.div`
|
|
618
|
+
gap: .5rem;
|
|
619
|
+
display: flex;
|
|
620
|
+
flex-direction: column;
|
|
621
|
+
cursor: pointer;
|
|
622
|
+
padding: .5rem;
|
|
623
|
+
border-radius: var(--bs-border-radius-lg);
|
|
624
|
+
|
|
625
|
+
&:hover {
|
|
626
|
+
background-color: var(--bs-gray-200);
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
&:hover {
|
|
630
|
+
${at} :last-child {
|
|
631
|
+
display: initial;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
`,ct=i(p)`
|
|
636
|
+
display: flex;
|
|
637
|
+
flex-direction: column;
|
|
638
|
+
padding: .5rem;
|
|
639
|
+
`,dt=i.div`
|
|
640
|
+
height: 100%;
|
|
641
|
+
overflow-y: auto;
|
|
642
|
+
`;var ht;function ut(){return ut=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},ut.apply(this,arguments)}const mt=e=>y.createElement("svg",ut({width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 256 256"},e),ht||(ht=y.createElement("path",{fillRule:"evenodd",d:"M128 22C69.458 22 22 69.458 22 128v96c0 5.523 4.477 10 10 10h96c58.542 0 106-47.458 106-106S186.542 22 128 22m0 56c5.523 0 10 4.477 10 10v30h30c5.523 0 10 4.477 10 10s-4.477 10-10 10h-30v30c0 5.523-4.477 10-10 10s-10-4.477-10-10v-30H88c-5.523 0-10-4.477-10-10s4.477-10 10-10h30V88c0-5.523 4.477-10 10-10",clipRule:"evenodd","data-follow-fill":"#000"})));function pt(){const{reset:t}=de();return e(rt,{className:"text-primary",tooltip:"新会话",placement:"top",onClick:t,children:e(mt,{})})}function gt(r){let{children:n}=r;return t(bt,{children:[n,t(ft,{children:[e(it,{}),e(pt,{})]})]})}const ft=i.div`
|
|
643
|
+
display: flex;
|
|
644
|
+
gap: .25rem;
|
|
645
|
+
margin-left: auto;
|
|
646
|
+
`,bt=i.div`
|
|
647
|
+
margin-bottom: .5rem;
|
|
648
|
+
display: flex;
|
|
649
|
+
padding: 0 .125rem;
|
|
650
|
+
`;var vt=q((function(r,n){let{suggestion:i,fileTypes:o,speech:a,scrollRef:s,variables:c,minRows:d,toolbar:u,disabled:p,autoFocus:g}=r;const f=E(null),b=E(null),x=E(null),[y,w]=C(""),[k,j]=C(""),[N,M]=v([]),[q,A]=C(!1),F=o&&o.length>0?o:Je,{messages:R,loading:D,request:I}=de(),{send:T}=function(e){let{suggestion:t,onSuccess:r}=e;const{setMessages:n,setSuggestions:i,setLoading:o,conversationId:a,setConversationId:s,request:l}=de(),c=E(null),d=$((async()=>{c.current=new AbortController;try{let e={method:"post",url:"/suggestion",data:{conversation:a},signal:c.current.signal};const t=await l(e);i(t)}catch{}finally{c.current=null}}),[a]),u=$((async function(e){if("string"==typeof e){for(var u=arguments.length,m=new Array(u>1?u-1:0),p=1;p<u;p++)m[p-1]=arguments[p];e={query:e,...m}}const{query:g,files:f=[],variables:b={},quote:v}=e;if(g||f.length>0){c.current&&c.current.abort(),o(!0),i([]),n((e=>{e.push({query:g,quote:v,files:f,variables:b,chunks:[],loading:!0})}));try{let e={method:"post",data:{query:g,quote:v,files:f,variables:b,conversation:a},onMessage:e=>{if(e.data)if("[DONE]"!=e.data)try{const t=JSON.parse(e.data);t.conversation?s(t.conversation):n((e=>{const r=e[e.length-1];if(r.chunks)if(t.chunks){const e=t.chunks.index;if(r.chunks[e]||(r.chunks[e]={content:"",tools:[]}),t.chunks.error)r.chunks[e].error=t.chunks.error;else if(t.chunks.tools){const n=t.chunks.tools.index;"response"in t.chunks.tools?(r.chunks[e].tools[n].response=t.chunks.tools.response,r.chunks[e].tools[n].error=t.chunks.tools.error,r.chunks[e].tools[n].content=t.chunks.tools.content):r.chunks[e].tools[n]={name:t.chunks.tools.name,title:t.chunks.tools.title,arguments:t.chunks.tools.arguments}}else t.chunks.content&&(r.chunks[e].content+=t.chunks.content)}else t.stats&&(r.stats=t.stats)}))}catch(e){console.error(e)}else n((e=>{e[e.length-1].loading=!1}))}};await l(e),t&&d()}catch(e){let t="未知错误";h(e)&&(t=401==e.response?.status?"未授权或授权已过期,请刷新页面后重试":"string"==typeof e.errors?e.errors:Object.values(e.errors).join("\n")),n((e=>{const r=e[e.length-1];r.chunks&&(0===r.chunks.length?r.chunks=[{content:`[${t}]`,tools:[]}]:r.chunks[r.chunks.length-1].content=`[${t}]`),r.loading=!1}))}o(!1),r?.()}}),[]);return{send:u}}({suggestion:i,onSuccess(){requestAnimationFrame((()=>{f.current?.focus()}))}}),[P,L]=C((()=>{const e=R.filter((e=>!!e.query));if(e.length>0){return e[e.length-1].variables}}));z((()=>{!o&&N.length>0&&M([])}),[o]),z((()=>{const e=s.current;if(e&&T){const t=e=>{e.target instanceof HTMLAnchorElement&&"#!question"===e.target.hash&&(e.preventDefault(),T(e.target.text))};return e.addEventListener("click",t),()=>{e.removeEventListener("click",t)}}}),[s,T]);const B=$((e=>{let{target:t}=e;if(t.files){const e=Array.from(t.files).filter((e=>!!F.includes(W.extname(e.name))&&(!(e.size>20971520)&&e))).slice(0,6-N.length);M((t=>{t.push(...e.map((e=>({file:e}))))})),e.forEach((async e=>{try{const t=new FormData;t.set("file",e);const r=await I({method:"POST",url:"/upload",data:t});M((t=>{const n=t.find((t=>t.file===e));n&&(n.path=r.path)}))}catch(t){const r=h(t)?t.message:"unknown error";M((t=>{const n=t.find((t=>t.file===e));n&&(n.error=r)}))}}))}t.value=""}),[N,F]),O=N.flatMap((e=>{let{file:t,path:r}=e;return r?[{name:t.name,size:t.size,path:r}]:[]})),_=$((()=>{if(y||O.length>0){const e={query:y,files:O};c&&(e.variables={...P,...c.values}),k&&(e.quote=k),T(e),w(""),j(""),M([]),x.current?.stop(!0)}}),[y,O,c,k]);if(S(n,(()=>({setQuery:w,setQuote:j,send:T,focus(){f.current?.focus()}}))),c){const t=c.config.filter((e=>!(e.key in(c.values||{})))),r=function(e){let r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return!!e&&t.every((t=>{const n=!t.required||e?.[t.key];return!n&&r&&m.error("请完善必填信息"),n}))};if(t.length>0&&!r(P))return e(yt,{children:e(xt,{children:e(Ve,{values:P,variables:t,onSubmit:e=>{let{formData:t}=e;if(r(t,!0))return L(t),!0}})})})}return t(Ct,{children:[u&&e(gt,{children:u}),t(Nt,{$focused:q&&!D,children:[N.length>0&&e(kt,{children:N.map(((t,r)=>{let{file:n,error:i,path:o}=t;const a=void 0===i&&void 0===o;return e(wt,{name:n.name,size:n.size,error:i,loading:a,onRemove:()=>{M((e=>{const t=e.findIndex((e=>e.file===n));-1!==t&&e.splice(t,1)}))}},r)}))}),!!k&&t(jt,{children:[e("i",{className:"bi bi-quote"}),e("p",{children:k}),e(Q,{onClick:()=>j("")})]}),t(Et,{children:[e(Y,{disabled:D||p,ref:f,placeholder:"请输入你的问题, Enter+Shift换行, Enter发送",minRows:d,maxRows:5,value:y,onChange:e=>w(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),_())},autoFocus:g,onFocus:()=>A(!0),onBlur:()=>A(!1)}),o&&e(l,{tooltip:"可上传不超过6个小于20MB的文件",placement:"top",children:t(Ye,{disabled:N.length>=6,onClick:()=>b.current?.click(),children:[e("input",{onChange:B,multiple:!0,accept:F.join(","),ref:b,type:"file",hidden:!0}),e("i",{className:"bi bi-file-earmark-arrow-up"})]})}),a&&e(et,{ref:x,model:a.model,onResult:e=>{f.current?.focus(),w((t=>t+e+" "))}}),e(Ye,{className:"text-primary",disabled:!y&&0===O.length,onClick:e=>{e.preventDefault(),_()},children:e("i",{className:"bi bi-send-fill"})})]})]})]})}));const xt=i.div`
|
|
577
651
|
border-radius: var(--bs-border-radius-lg);
|
|
578
652
|
box-shadow: var(--bs-box-shadow-sm);
|
|
579
653
|
margin: 1rem;
|
|
580
654
|
padding: 1rem;
|
|
581
655
|
width: 100%;
|
|
582
656
|
max-width: 500px;
|
|
583
|
-
`,
|
|
657
|
+
`,yt=i.div`
|
|
584
658
|
position: absolute;
|
|
585
659
|
left: 0;
|
|
586
660
|
right: 0;
|
|
@@ -590,15 +664,15 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
590
664
|
display: flex;
|
|
591
665
|
justify-content: center;
|
|
592
666
|
align-items: center;
|
|
593
|
-
`,
|
|
667
|
+
`,wt=i(Ee)`
|
|
594
668
|
width: calc((100% - .75rem) / 2);
|
|
595
|
-
`,
|
|
669
|
+
`,kt=i.div`
|
|
596
670
|
display: flex;
|
|
597
671
|
flex-wrap: wrap;
|
|
598
672
|
padding: .75rem;
|
|
599
673
|
gap: .75rem;
|
|
600
674
|
border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color);
|
|
601
|
-
`,
|
|
675
|
+
`,Et=i.div`
|
|
602
676
|
display: flex;
|
|
603
677
|
padding: .5rem .5rem .5rem 1rem;
|
|
604
678
|
gap: .25rem;
|
|
@@ -615,7 +689,7 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
615
689
|
color: rgba(54, 54, 54, .3);
|
|
616
690
|
}
|
|
617
691
|
}
|
|
618
|
-
`,
|
|
692
|
+
`,jt=i.div`
|
|
619
693
|
margin: .75rem .75rem 0 .75rem;
|
|
620
694
|
padding: 4px 8px;
|
|
621
695
|
display: flex;
|
|
@@ -636,14 +710,14 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
636
710
|
-webkit-box-orient: vertical;
|
|
637
711
|
display: -webkit-box;
|
|
638
712
|
}
|
|
639
|
-
`,
|
|
713
|
+
`,Nt=i.div`
|
|
640
714
|
background: #FFF;
|
|
641
715
|
border: var(--bs-border-width) var(--bs-border-style) ${e=>e.$focused?"var(--bs-primary)":"var(--bs-border-color)"};
|
|
642
716
|
border-radius: var(--bs-border-radius-lg);
|
|
643
717
|
box-shadow: 0.125rem 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
|
|
644
|
-
`,
|
|
718
|
+
`,Ct=i.div`
|
|
645
719
|
margin: 0 1rem 1rem;
|
|
646
|
-
|
|
720
|
+
`;function Mt(e){if((e=e.filter((e=>!!e.trim()))).length>3){const t=[...e];let r=e.length-3;for(;r--;){let e=Math.floor(Math.random()*t.length);t.splice(e,1)}e=t}return e}const qt=w(q(((r,i)=>{let{className:o,bot:a,user:s,input:l,logLevel:c,imageResolver:d,placeholder:h,actions:u,onboarding:m,conversation:p,cite:g,speech:f,request:b}=r;const y=$((e=>{const t=[];if(m&&!1!==m.enable){const e=Mt(m.questions||[]);t.push({chunks:[{content:[m.prologue,...e.map((e=>`[${e}](#!question)`))].join("\n"),tools:[]}],loading:m.loading})}return e?t.concat(function(e){return e.map((e=>({id:e.id,query:e.query,quote:e.quote||void 0,files:e.files||void 0,variables:e.variables,chunks:e.chunks.map((e=>{let{content:t="",error:r,tools:n=[]}=e;return{content:t,error:r,tools:n}})),annotation:e.annotation,stats:{usage:e.usage,latency:e.latency}})))}(e.messages||[])):t}),[m]),[w,j]=C(p?.id),[N,M]=v([]);z((()=>{M(y(p))}),[m]);const[q,A]=C(!1),F=E(!l),R=E(null),D=$((()=>{const e=R.current;e&&requestAnimationFrame((()=>{e.scrollTo({top:e.scrollHeight})}))}),[]),{ref:I,height:T}=G(),[P,L]=C([]);z((()=>{(q||!F.current)&&N.length>0&&(q&&(F.current=!0),D())}),[T,q,F,N]),z((()=>{P.length>0&&D()}),[P]);const B=$((e=>{q||(j(e?.id),M(y(e)),L([]))}),[q,y]);return S(i,(()=>({reset:B})),[B]),e(he,{request:k((()=>b?"string"==typeof b?x.create({baseURL:b}):b:x),[b]),bot:a,user:s,logLevel:c,imageResolver:d,conversationId:w,setConversationId:j,messages:N,setMessages:M,suggestions:P,setSuggestions:L,loading:q,setLoading:A,reset:B,children:e(At,{className:o,children:t(n,{children:[e($t,{ref:R,children:t(St,{ref:I,children:[0===N.length&&h,N.slice(-30).map(((t,r)=>e(Te,{actions:u,cite:g,speech:f,message:t,updater:e=>{M((r=>{const n=r.findIndex((e=>e.id===t.id));-1!==n&&e(r[n])}))}},r))),P.length>0&&e(zt,{children:P.map(((t,r)=>e("a",{href:"#!question",children:t},r)))})]})}),l&&e(vt,{...l,scrollRef:R})]})})})})),O),zt=i.div`
|
|
647
721
|
display: flex;
|
|
648
722
|
flex-direction: column;
|
|
649
723
|
align-items: flex-start;
|
|
@@ -660,20 +734,20 @@ import*as e from"react";import{useCallback as t,useEffect as r,useState as n,use
|
|
|
660
734
|
background: var(--bs-secondary-bg-subtle);
|
|
661
735
|
}
|
|
662
736
|
}
|
|
663
|
-
|
|
737
|
+
`,$t=i.div`
|
|
664
738
|
display: flex;
|
|
665
739
|
flex-direction: column;
|
|
666
740
|
flex: 1;
|
|
667
741
|
overflow-y: auto;
|
|
668
742
|
padding: 0 1rem;
|
|
669
743
|
margin-bottom: .5rem;
|
|
670
|
-
`,
|
|
744
|
+
`,St=i.div`
|
|
671
745
|
display: flex;
|
|
672
746
|
flex-direction: column;
|
|
673
747
|
flex: 1;
|
|
674
|
-
`,
|
|
748
|
+
`,At=i.div`
|
|
675
749
|
display: flex;
|
|
676
750
|
flex-direction: column;
|
|
677
751
|
height: 100%;
|
|
678
752
|
position: relative;
|
|
679
|
-
`;export{
|
|
753
|
+
`;export{rt as ActionButton,oe as Markdown,qt as MessageBox,Ve as VariableForm,Mt as pickQuestions,Fe as useSynthesis};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topthink/chat",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prebuild": "rimraf es types",
|
|
6
6
|
"build": "rollup -c --environment NODE_ENV:production",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@babel/runtime": "^7.11.2",
|
|
20
20
|
"@breezystack/lamejs": "^1.2.7",
|
|
21
|
-
"@topthink/components": "^1.0
|
|
21
|
+
"@topthink/components": "^1.1.0",
|
|
22
22
|
"@types/mdast": "^4.0.4",
|
|
23
23
|
"eventemitter3": "^5.0.1",
|
|
24
24
|
"katex": "^0.16.9",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
},
|
|
66
66
|
"author": "yunwuxin <tzzhangyajun@qq.com> (https://github.com/yunwuxin)",
|
|
67
67
|
"license": "MIT",
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "60aa34ea284af9a97a531a1ab5589d38f4792ee5"
|
|
69
69
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
tooltip?: string;
|
|
5
|
+
placement?: 'top' | 'bottom';
|
|
6
|
+
onClick?: MouseEventHandler<HTMLDivElement>;
|
|
7
|
+
onMouseDown?: MouseEventHandler<HTMLDivElement>;
|
|
8
|
+
className?: string;
|
|
9
|
+
size?: 'sm';
|
|
10
|
+
}
|
|
11
|
+
declare const ActionButton: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<HTMLDivElement>>;
|
|
12
|
+
export default ActionButton;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { PropsWithChildren } from 'react';
|
|
2
|
-
import { LogLevel } from '../../types';
|
|
1
|
+
import { Dispatch, PropsWithChildren, SetStateAction } from 'react';
|
|
2
|
+
import { Conversation, LogLevel, Message } from '../../types';
|
|
3
|
+
import { Updater } from '@topthink/components/types/hooks/use-immer';
|
|
4
|
+
import { RequestInstance } from '@topthink/components';
|
|
3
5
|
interface ContextType {
|
|
4
6
|
bot: {
|
|
5
7
|
name: string;
|
|
@@ -9,8 +11,18 @@ interface ContextType {
|
|
|
9
11
|
name: string;
|
|
10
12
|
avatar: string;
|
|
11
13
|
};
|
|
14
|
+
request: RequestInstance;
|
|
12
15
|
imageResolver?: (url: string) => string;
|
|
13
16
|
logLevel?: LogLevel;
|
|
17
|
+
conversationId?: string;
|
|
18
|
+
setConversationId: Dispatch<SetStateAction<string | undefined>>;
|
|
19
|
+
messages: Message[];
|
|
20
|
+
setMessages: Updater<Message[]>;
|
|
21
|
+
suggestions: string[];
|
|
22
|
+
setSuggestions: Dispatch<SetStateAction<string[]>>;
|
|
23
|
+
loading: boolean;
|
|
24
|
+
setLoading: Dispatch<SetStateAction<boolean>>;
|
|
25
|
+
reset: (conversation?: Conversation) => void;
|
|
14
26
|
}
|
|
15
27
|
export declare function useContext(): ContextType;
|
|
16
28
|
export declare function Provider({ children, ...props }: PropsWithChildren<ContextType>): JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { RequestInstance } from '@topthink/components';
|
|
1
2
|
import { MutableRefObject, ReactNode } from 'react';
|
|
2
|
-
import { ConversationMessage, Input, LogLevel, Variable } from '../../types';
|
|
3
|
-
import { ChatOptions } from '../../hooks/use-chat';
|
|
3
|
+
import { Conversation, ConversationMessage, Input, LogLevel, MessageBoxType, Variable } from '../../types';
|
|
4
4
|
import { MessageActions } from './message-item';
|
|
5
5
|
import { Components } from 'react-markdown';
|
|
6
6
|
interface Props {
|
|
@@ -14,11 +14,17 @@ interface Props {
|
|
|
14
14
|
avatar: string;
|
|
15
15
|
};
|
|
16
16
|
messages?: ConversationMessage[];
|
|
17
|
+
conversation?: Conversation;
|
|
17
18
|
speech?: {
|
|
18
19
|
model?: string;
|
|
19
20
|
voice?: string;
|
|
20
21
|
autoplay?: boolean;
|
|
21
|
-
|
|
22
|
+
};
|
|
23
|
+
onboarding?: {
|
|
24
|
+
enable?: boolean;
|
|
25
|
+
prologue: string;
|
|
26
|
+
questions?: string[];
|
|
27
|
+
loading?: boolean;
|
|
22
28
|
};
|
|
23
29
|
placeholder?: ReactNode;
|
|
24
30
|
logLevel?: LogLevel;
|
|
@@ -30,7 +36,7 @@ interface Props {
|
|
|
30
36
|
model?: string;
|
|
31
37
|
};
|
|
32
38
|
minRows?: number;
|
|
33
|
-
|
|
39
|
+
suggestion?: boolean;
|
|
34
40
|
toolbar?: ReactNode;
|
|
35
41
|
autoFocus?: boolean;
|
|
36
42
|
variables?: {
|
|
@@ -39,8 +45,9 @@ interface Props {
|
|
|
39
45
|
};
|
|
40
46
|
ref?: MutableRefObject<Input | null>;
|
|
41
47
|
};
|
|
48
|
+
request?: RequestInstance | string;
|
|
42
49
|
actions?: MessageActions;
|
|
43
50
|
cite?: Components['cite'];
|
|
44
51
|
}
|
|
45
|
-
declare const MessageBox: import("react").MemoExoticComponent<(
|
|
52
|
+
declare const MessageBox: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<MessageBoxType>>>;
|
|
46
53
|
export default MessageBox;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { MutableRefObject, ReactNode } from 'react';
|
|
2
|
-
import { Input,
|
|
3
|
-
import { ChatOptions } from '../../../hooks/use-chat';
|
|
2
|
+
import { Input, Variable } from '../../../types';
|
|
4
3
|
interface Props {
|
|
5
|
-
|
|
4
|
+
suggestion?: boolean;
|
|
6
5
|
variables?: {
|
|
7
6
|
config: Variable[];
|
|
8
7
|
values?: Record<string, string>;
|
|
@@ -13,11 +12,8 @@ interface Props {
|
|
|
13
12
|
};
|
|
14
13
|
minRows?: number;
|
|
15
14
|
scrollRef: MutableRefObject<HTMLDivElement | null>;
|
|
16
|
-
|
|
17
|
-
onSuggestions: (suggestions: string[]) => void;
|
|
18
|
-
toolbar?: ReactNode;
|
|
15
|
+
toolbar?: ReactNode | true;
|
|
19
16
|
disabled?: boolean;
|
|
20
|
-
onLoading?: (loading: boolean) => void;
|
|
21
17
|
autoFocus?: boolean;
|
|
22
18
|
}
|
|
23
19
|
declare const _default: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<Input>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ChatOptions {
|
|
2
|
+
suggestion?: boolean;
|
|
3
|
+
onSuccess?: () => void;
|
|
4
|
+
}
|
|
5
|
+
export default function useChat({ suggestion, onSuccess, }: ChatOptions): {
|
|
6
|
+
send: (params: string | import("../../../types").ChatParams, files?: {
|
|
7
|
+
path: string;
|
|
8
|
+
name: string;
|
|
9
|
+
size: number;
|
|
10
|
+
}[] | undefined, variables?: Record<string, string> | undefined) => void;
|
|
11
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
2
|
interface Props {
|
|
3
|
-
url: string;
|
|
4
3
|
model?: string;
|
|
5
4
|
voice?: string;
|
|
6
5
|
loading?: boolean;
|
|
@@ -8,5 +7,5 @@ interface Props {
|
|
|
8
7
|
contentRef: RefObject<HTMLDivElement>;
|
|
9
8
|
autoplay?: boolean;
|
|
10
9
|
}
|
|
11
|
-
export default function SpeechAction({
|
|
10
|
+
export default function SpeechAction({ model, voice, loading, autoplay, contentRef, avatarRef }: Props): JSX.Element;
|
|
12
11
|
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './types';
|
|
2
|
-
export { default as useChat } from './hooks/use-chat';
|
|
3
2
|
export { default as MessageBox } from './components/message-box';
|
|
3
|
+
export { default as ActionButton } from './components/action-button';
|
|
4
4
|
export { default as Markdown } from './components/markdown';
|
|
5
5
|
export { default as VariableForm } from './components/variable-form';
|
|
6
6
|
export { default as pickQuestions } from './utils/pick-questions';
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Recognition } from '../../types';
|
|
2
|
+
export interface Loader {
|
|
3
|
+
(blob: Blob): Promise<string | undefined>;
|
|
4
|
+
}
|
|
2
5
|
export default class Custom implements Recognition {
|
|
3
6
|
#private;
|
|
4
|
-
constructor(
|
|
7
|
+
constructor(loader: Loader);
|
|
5
8
|
start(): Promise<void>;
|
|
6
9
|
private convertBuffer;
|
|
7
10
|
private encodeMP3;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Synthesis } from '../../types';
|
|
2
|
+
export interface Loader {
|
|
3
|
+
(text: string): Promise<{
|
|
4
|
+
type: string;
|
|
5
|
+
data: string;
|
|
6
|
+
}>;
|
|
7
|
+
}
|
|
2
8
|
export default class Custom implements Synthesis {
|
|
3
9
|
#private;
|
|
4
|
-
constructor(
|
|
10
|
+
constructor(loader: Loader);
|
|
5
11
|
protected createLoader(text: string): Promise<HTMLAudioElement | undefined>;
|
|
6
12
|
protected loadAudioData(): Promise<void>;
|
|
7
13
|
protected waitForAudioLoaded(text: string): Promise<HTMLAudioElement | undefined>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { Loader } from './recognition/custom';
|
|
1
2
|
interface Config {
|
|
2
|
-
model?: string;
|
|
3
|
-
url: string;
|
|
4
3
|
onResult: (transcript: string) => void;
|
|
4
|
+
loader?: Loader;
|
|
5
5
|
}
|
|
6
|
-
export default function useRecognition({ onResult,
|
|
6
|
+
export default function useRecognition({ onResult, loader }: Config): {
|
|
7
7
|
recording: boolean;
|
|
8
8
|
transcribing: boolean;
|
|
9
9
|
start: () => Promise<void>;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
|
+
import { Loader } from './synthesis/custom';
|
|
2
3
|
interface Config {
|
|
3
4
|
text: string | RefObject<HTMLDivElement>;
|
|
4
|
-
|
|
5
|
-
voice?: string;
|
|
5
|
+
loader?: Loader;
|
|
6
6
|
loading?: boolean;
|
|
7
|
-
url: string;
|
|
8
7
|
}
|
|
9
|
-
export default function useSynthesis({ text,
|
|
8
|
+
export default function useSynthesis({ text, loading, loader }: Config): {
|
|
10
9
|
playing: boolean;
|
|
11
10
|
speaking: boolean;
|
|
12
11
|
start: (append?: boolean) => Promise<void>;
|
package/types/types.d.ts
CHANGED
|
@@ -78,9 +78,11 @@ export interface ChatParams {
|
|
|
78
78
|
variables?: Record<string, string>;
|
|
79
79
|
}
|
|
80
80
|
export interface Chat {
|
|
81
|
-
reset(conversation?: Conversation): void;
|
|
82
81
|
send(params: string | ChatParams, files?: Message['files'], variables?: Message['variables']): void;
|
|
83
82
|
}
|
|
83
|
+
export interface MessageBoxType {
|
|
84
|
+
reset(conversation?: Conversation): void;
|
|
85
|
+
}
|
|
84
86
|
export interface Input extends Chat {
|
|
85
87
|
setQuery(query: string): void;
|
|
86
88
|
setQuote(quote: string): void;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { MutableRefObject } from 'react';
|
|
2
|
-
import { Chat, Conversation, Message } from '../types';
|
|
3
|
-
import { RequestConfig } from '@topthink/components';
|
|
4
|
-
export interface ChatOptions {
|
|
5
|
-
url: string;
|
|
6
|
-
transformRequest?: (scene: 'chat' | 'upload' | 'suggestion', config: Exclude<RequestConfig, string>) => Exclude<RequestConfig, string>;
|
|
7
|
-
onSuccess?: () => void;
|
|
8
|
-
onboarding?: {
|
|
9
|
-
enable?: boolean;
|
|
10
|
-
prologue: string;
|
|
11
|
-
questions?: string[];
|
|
12
|
-
loading?: boolean;
|
|
13
|
-
};
|
|
14
|
-
suggestion?: {
|
|
15
|
-
enable?: boolean;
|
|
16
|
-
};
|
|
17
|
-
conversation?: Conversation;
|
|
18
|
-
ref?: MutableRefObject<Chat | null>;
|
|
19
|
-
}
|
|
20
|
-
export default function useChat({ url, onboarding, suggestion, onSuccess, ref, transformRequest, ...props }: ChatOptions): {
|
|
21
|
-
messages: Message[];
|
|
22
|
-
suggestions: string[];
|
|
23
|
-
loading: boolean;
|
|
24
|
-
send: (params: string | import("../types").ChatParams, files?: {
|
|
25
|
-
path: string;
|
|
26
|
-
name: string;
|
|
27
|
-
size: number;
|
|
28
|
-
}[] | undefined, variables?: Record<string, string> | undefined) => void;
|
|
29
|
-
reset: (conversation?: Conversation) => void;
|
|
30
|
-
};
|