mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-04-08 03:14:17 +00:00
test webui
This commit is contained in:
parent
665014c81e
commit
e76f870cae
26
web/dist/assets/index-5mBsl5lX.css
vendored
26
web/dist/assets/index-5mBsl5lX.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
import{b as q,d as P,q as g,r as l,L as c,u as i,s as R,t as r,E as p}from"./index-BXY6uktx.js";const b=1,$=33,m=34,v=35,x=36,d=new p(O=>{let e=O.pos;for(;;){if(O.next==10){O.advance();break}else if(O.next==123&&O.peek(1)==123||O.next<0)break;O.advance()}O.pos>e&&O.acceptToken(b)});function n(O,e,a){return new p(t=>{let u=t.pos;for(;t.next!=O&&t.next>=0&&(a||t.next!=38&&(t.next!=123||t.peek(1)!=123));)t.advance();t.pos>u&&t.acceptToken(e)})}const W=n(39,$,!1),C=n(34,m,!1),T=n(39,v,!0),f=n(34,x,!0),A=c.deserialize({version:14,states:"(jOVOqOOOeQpOOOvO!bO'#CaOOOP'#Cx'#CxQVOqOOO!OQpO'#CfO!WQpO'#ClO!]QpO'#CrO!bQpO'#CsOOQO'#Cv'#CvQ!gQpOOQ!lQpOOQ!qQpOOOOOV,58{,58{O!vOpO,58{OOOP-E6v-E6vO!{QpO,59QO#TQpO,59QOOQO,59W,59WO#YQpO,59^OOQO,59_,59_O#_QpOOO#_QpOOO#gQpOOOOOV1G.g1G.gO#oQpO'#CyO#tQpO1G.lOOQO1G.l1G.lO#|QpO1G.lOOQO1G.x1G.xO$UO`O'#DUO$ZOWO'#DUOOQO'#Co'#CoQOQpOOOOQO'#Cu'#CuO$`OtO'#CwO$qOrO'#CwOOQO,59e,59eOOQO-E6w-E6wOOQO7+$W7+$WO%SQpO7+$WO%[QpO7+$WOOOO'#Cp'#CpO%aOpO,59pOOOO'#Cq'#CqO%fOpO,59pOOOS'#Cz'#CzO%kOtO,59cOOQO,59c,59cOOOQ'#C{'#C{O%|OrO,59cO&_QpO<<GrOOQO<<Gr<<GrOOQO1G/[1G/[OOOS-E6x-E6xOOQO1G.}1G.}OOOQ-E6y-E6yOOQOAN=^AN=^",stateData:"&d~OvOS~OPROSQOVROWRO~OZTO[XO^VOaUOhWO~OR]OU^O~O[`O^aO~O[bO~O[cO~O[dO~ObeO~ObfO~ObgO~ORhO~O]kOwiO~O[lO~O_mO~OynOzoO~OysOztO~O[uO~O]wOwiO~O_yOwiO~OtzO~Os|O~OSQOV!OOW!OOr!OOy!QO~OSQOV!ROW!ROq!ROz!QO~O_!TOwiO~O]!UO~Oy!VO~Oz!VO~OSQOV!OOW!OOr!OOy!XO~OSQOV!ROW!ROq!ROz!XO~O]!ZO~O",goto:"#dyPPPPPzPPPP!WPPPPP!WPP!Z!^!a!d!dP!g!j!m!p!v#Q#WPPPPPPPP#^SROSS!Os!PT!Rt!SRYPRqeR{nR}oRZPRqfR[PRqgQSOR_SQj`SvjxRxlQ!PsR!W!PQ!StR!Y!SQpeRrf",nodeNames:"⚠ Text Content }} {{ Interpolation InterpolationContent Entity InvalidEntity Attribute BoundAttributeName [ Identifier ] ( ) ReferenceName # Is ExpressionAttributeValue AttributeInterpolation AttributeInterpolation EventName DirectiveName * StatementAttributeValue AttributeName AttributeValue",maxTerm:42,nodeProps:[["openedBy",3,"{{",15,"("],["closedBy",4,"}}",14,")"],["isolate",-4,5,19,25,27,""]],skippedNodes:[0],repeatNodeCount:4,tokenData:"0r~RyOX#rXY$mYZ$mZ]#r]^$m^p#rpq$mqr#rrs%jst&Qtv#rvw&hwx)zxy*byz*xz{+`{}#r}!O+v!O!P-]!P!Q#r!Q![+v![!]+v!]!_#r!_!`-s!`!c#r!c!}+v!}#O.Z#O#P#r#P#Q.q#Q#R#r#R#S+v#S#T#r#T#o+v#o#p/X#p#q#r#q#r0Z#r%W#r%W;'S+v;'S;:j-V;:j;=`$g<%lO+vQ#wTUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rQ$ZSO#q#r#r;'S#r;'S;=`$g<%lO#rQ$jP;=`<%l#rR$t[UQvPOX#rXY$mYZ$mZ]#r]^$m^p#rpq$mq#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR%qTyPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR&XTaPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR&oXUQWPOp'[pq#rq!]'[!]!^#r!^#q'[#q#r(d#r;'S'[;'S;=`)t<%lO'[R'aXUQOp'[pq#rq!]'[!]!^'|!^#q'[#q#r(d#r;'S'[;'S;=`)t<%lO'[R(TTVPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR(gXOp'[pq#rq!]'[!]!^'|!^#q'[#q#r)S#r;'S'[;'S;=`)t<%lO'[P)VUOp)Sq!])S!]!^)i!^;'S)S;'S;=`)n<%lO)SP)nOVPP)qP;=`<%l)SR)wP;=`<%l'[R*RTzPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR*iT^PUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR+PT_PUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR+gThPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR+}b[PUQO}#r}!O+v!O!Q#r!Q![+v![!]+v!]!c#r!c!}+v!}#R#r#R#S+v#S#T#r#T#o+v#o#q#r#q#r$W#r%W#r%W;'S+v;'S;:j-V;:j;=`$g<%lO+vR-YP;=`<%l+vR-dTwPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR-zTUQbPO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR.bTZPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR.xT]PUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR/^VUQO#o#r#o#p/s#p#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR/zTSPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#r~0^TO#q#r#q#r0m#r;'S#r;'S;=`$g<%lO#r~0rOR~",tokenizers:[d,W,C,T,f,0,1],topRules:{Content:[0,2],Attribute:[1,9]},tokenPrec:0}),V=i.parser.configure({top:"SingleExpression"}),Q=A.configure({props:[R({Text:r.content,Is:r.definitionOperator,AttributeName:r.attributeName,"AttributeValue ExpressionAttributeValue StatementAttributeValue":r.attributeValue,Entity:r.character,InvalidEntity:r.invalid,"BoundAttributeName/Identifier":r.attributeName,"EventName/Identifier":r.special(r.attributeName),"ReferenceName/Identifier":r.variableName,"DirectiveName/Identifier":r.keyword,"{{ }}":r.brace,"( )":r.paren,"[ ]":r.bracket,"# '*'":r.punctuation})]}),o={parser:V},w={parser:i.parser},U=Q.configure({wrap:l((O,e)=>O.name=="InterpolationContent"?o:null)}),y=Q.configure({wrap:l((O,e)=>{var a;return O.name=="InterpolationContent"?o:O.name!="AttributeInterpolation"?null:((a=O.node.parent)===null||a===void 0?void 0:a.name)=="StatementAttributeValue"?w:o}),top:"Attribute"}),E={parser:U},N={parser:y},s=g();function S(O){return O.configure({wrap:l(z)},"angular")}const k=S(s.language);function z(O,e){switch(O.name){case"Attribute":return/^[*#(\[]|\{\{/.test(e.read(O.from,O.to))?N:null;case"Text":return E}return null}function G(O={}){let e=s;if(O.base){if(O.base.language.name!="html"||!(O.base.language instanceof q))throw new RangeError("The base option must be the result of calling html(...)");e=O.base}return new P(e.language==s.language?k:S(e.language),[e.support,e.language.data.of({closeBrackets:{brackets:["[","{",'"']},indentOnInput:/^\s*[\}\]]$/})])}export{G as angular,k as angularLanguage};
|
||||
import{b as q,d as P,q as g,r as l,L as c,u as i,s as R,t as r,E as p}from"./index-7Pb28EN0.js";const b=1,$=33,m=34,v=35,x=36,d=new p(O=>{let e=O.pos;for(;;){if(O.next==10){O.advance();break}else if(O.next==123&&O.peek(1)==123||O.next<0)break;O.advance()}O.pos>e&&O.acceptToken(b)});function n(O,e,a){return new p(t=>{let u=t.pos;for(;t.next!=O&&t.next>=0&&(a||t.next!=38&&(t.next!=123||t.peek(1)!=123));)t.advance();t.pos>u&&t.acceptToken(e)})}const W=n(39,$,!1),C=n(34,m,!1),T=n(39,v,!0),f=n(34,x,!0),A=c.deserialize({version:14,states:"(jOVOqOOOeQpOOOvO!bO'#CaOOOP'#Cx'#CxQVOqOOO!OQpO'#CfO!WQpO'#ClO!]QpO'#CrO!bQpO'#CsOOQO'#Cv'#CvQ!gQpOOQ!lQpOOQ!qQpOOOOOV,58{,58{O!vOpO,58{OOOP-E6v-E6vO!{QpO,59QO#TQpO,59QOOQO,59W,59WO#YQpO,59^OOQO,59_,59_O#_QpOOO#_QpOOO#gQpOOOOOV1G.g1G.gO#oQpO'#CyO#tQpO1G.lOOQO1G.l1G.lO#|QpO1G.lOOQO1G.x1G.xO$UO`O'#DUO$ZOWO'#DUOOQO'#Co'#CoQOQpOOOOQO'#Cu'#CuO$`OtO'#CwO$qOrO'#CwOOQO,59e,59eOOQO-E6w-E6wOOQO7+$W7+$WO%SQpO7+$WO%[QpO7+$WOOOO'#Cp'#CpO%aOpO,59pOOOO'#Cq'#CqO%fOpO,59pOOOS'#Cz'#CzO%kOtO,59cOOQO,59c,59cOOOQ'#C{'#C{O%|OrO,59cO&_QpO<<GrOOQO<<Gr<<GrOOQO1G/[1G/[OOOS-E6x-E6xOOQO1G.}1G.}OOOQ-E6y-E6yOOQOAN=^AN=^",stateData:"&d~OvOS~OPROSQOVROWRO~OZTO[XO^VOaUOhWO~OR]OU^O~O[`O^aO~O[bO~O[cO~O[dO~ObeO~ObfO~ObgO~ORhO~O]kOwiO~O[lO~O_mO~OynOzoO~OysOztO~O[uO~O]wOwiO~O_yOwiO~OtzO~Os|O~OSQOV!OOW!OOr!OOy!QO~OSQOV!ROW!ROq!ROz!QO~O_!TOwiO~O]!UO~Oy!VO~Oz!VO~OSQOV!OOW!OOr!OOy!XO~OSQOV!ROW!ROq!ROz!XO~O]!ZO~O",goto:"#dyPPPPPzPPPP!WPPPPP!WPP!Z!^!a!d!dP!g!j!m!p!v#Q#WPPPPPPPP#^SROSS!Os!PT!Rt!SRYPRqeR{nR}oRZPRqfR[PRqgQSOR_SQj`SvjxRxlQ!PsR!W!PQ!StR!Y!SQpeRrf",nodeNames:"⚠ Text Content }} {{ Interpolation InterpolationContent Entity InvalidEntity Attribute BoundAttributeName [ Identifier ] ( ) ReferenceName # Is ExpressionAttributeValue AttributeInterpolation AttributeInterpolation EventName DirectiveName * StatementAttributeValue AttributeName AttributeValue",maxTerm:42,nodeProps:[["openedBy",3,"{{",15,"("],["closedBy",4,"}}",14,")"],["isolate",-4,5,19,25,27,""]],skippedNodes:[0],repeatNodeCount:4,tokenData:"0r~RyOX#rXY$mYZ$mZ]#r]^$m^p#rpq$mqr#rrs%jst&Qtv#rvw&hwx)zxy*byz*xz{+`{}#r}!O+v!O!P-]!P!Q#r!Q![+v![!]+v!]!_#r!_!`-s!`!c#r!c!}+v!}#O.Z#O#P#r#P#Q.q#Q#R#r#R#S+v#S#T#r#T#o+v#o#p/X#p#q#r#q#r0Z#r%W#r%W;'S+v;'S;:j-V;:j;=`$g<%lO+vQ#wTUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rQ$ZSO#q#r#r;'S#r;'S;=`$g<%lO#rQ$jP;=`<%l#rR$t[UQvPOX#rXY$mYZ$mZ]#r]^$m^p#rpq$mq#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR%qTyPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR&XTaPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR&oXUQWPOp'[pq#rq!]'[!]!^#r!^#q'[#q#r(d#r;'S'[;'S;=`)t<%lO'[R'aXUQOp'[pq#rq!]'[!]!^'|!^#q'[#q#r(d#r;'S'[;'S;=`)t<%lO'[R(TTVPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR(gXOp'[pq#rq!]'[!]!^'|!^#q'[#q#r)S#r;'S'[;'S;=`)t<%lO'[P)VUOp)Sq!])S!]!^)i!^;'S)S;'S;=`)n<%lO)SP)nOVPP)qP;=`<%l)SR)wP;=`<%l'[R*RTzPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR*iT^PUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR+PT_PUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR+gThPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR+}b[PUQO}#r}!O+v!O!Q#r!Q![+v![!]+v!]!c#r!c!}+v!}#R#r#R#S+v#S#T#r#T#o+v#o#q#r#q#r$W#r%W#r%W;'S+v;'S;:j-V;:j;=`$g<%lO+vR-YP;=`<%l+vR-dTwPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR-zTUQbPO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR.bTZPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR.xT]PUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR/^VUQO#o#r#o#p/s#p#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#rR/zTSPUQO#q#r#q#r$W#r;'S#r;'S;=`$g<%lO#r~0^TO#q#r#q#r0m#r;'S#r;'S;=`$g<%lO#r~0rOR~",tokenizers:[d,W,C,T,f,0,1],topRules:{Content:[0,2],Attribute:[1,9]},tokenPrec:0}),V=i.parser.configure({top:"SingleExpression"}),Q=A.configure({props:[R({Text:r.content,Is:r.definitionOperator,AttributeName:r.attributeName,"AttributeValue ExpressionAttributeValue StatementAttributeValue":r.attributeValue,Entity:r.character,InvalidEntity:r.invalid,"BoundAttributeName/Identifier":r.attributeName,"EventName/Identifier":r.special(r.attributeName),"ReferenceName/Identifier":r.variableName,"DirectiveName/Identifier":r.keyword,"{{ }}":r.brace,"( )":r.paren,"[ ]":r.bracket,"# '*'":r.punctuation})]}),o={parser:V},w={parser:i.parser},U=Q.configure({wrap:l((O,e)=>O.name=="InterpolationContent"?o:null)}),y=Q.configure({wrap:l((O,e)=>{var a;return O.name=="InterpolationContent"?o:O.name!="AttributeInterpolation"?null:((a=O.node.parent)===null||a===void 0?void 0:a.name)=="StatementAttributeValue"?w:o}),top:"Attribute"}),E={parser:U},N={parser:y},s=g();function S(O){return O.configure({wrap:l(z)},"angular")}const k=S(s.language);function z(O,e){switch(O.name){case"Attribute":return/^[*#(\[]|\{\{/.test(e.read(O.from,O.to))?N:null;case"Text":return E}return null}function G(O={}){let e=s;if(O.base){if(O.base.language.name!="html"||!(O.base.language instanceof q))throw new RangeError("The base option must be the result of calling html(...)");e=O.base}return new P(e.language==s.language?k:S(e.language),[e.support,e.language.data.of({closeBrackets:{brackets:["[","{",'"']},indentOnInput:/^\s*[\}\]]$/})])}export{G as angular,k as angularLanguage};
|
26
web/dist/assets/index-CnmZeAO0.css
vendored
Normal file
26
web/dist/assets/index-CnmZeAO0.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
import{b as O,d as b,L as r,f as s,g as a,s as t,j as P,l as n,t as e}from"./index-BXY6uktx.js";const S={__proto__:null,anyref:34,dataref:34,eqref:34,externref:34,i31ref:34,funcref:34,i8:34,i16:34,i32:34,i64:34,f32:34,f64:34},Q=r.deserialize({version:14,states:"!^Q]QPOOOqQPO'#CbOOQO'#Cd'#CdOOQO'#Cl'#ClOOQO'#Ch'#ChQ]QPOOOOQO,58|,58|OxQPO,58|OOQO-E6f-E6fOOQO1G.h1G.h",stateData:"!P~O_OSPOSQOS~OTPOVROXROYROZROaQO~OSUO~P]OSXO~P]O",goto:"xaPPPPPPbPbPPPhPPPrXROPTVQTOQVPTWTVXSOPTV",nodeNames:"⚠ LineComment BlockComment Module ) ( App Identifier Type Keyword Number String",maxTerm:17,nodeProps:[["isolate",-3,1,2,11,""],["openedBy",4,"("],["closedBy",5,")"],["group",-6,6,7,8,9,10,11,"Expression"]],skippedNodes:[0,1,2],repeatNodeCount:1,tokenData:"0o~R^XY}YZ}]^}pq}rs!Stu#pxy'Uyz(e{|(j}!O(j!Q!R(s!R![*p!]!^.^#T#o.{~!SO_~~!VVOr!Srs!ls#O!S#O#P!q#P;'S!S;'S;=`#j<%lO!S~!qOZ~~!tRO;'S!S;'S;=`!};=`O!S~#QWOr!Srs!ls#O!S#O#P!q#P;'S!S;'S;=`#j;=`<%l!S<%lO!S~#mP;=`<%l!S~#siqr%bst%btu%buv%bvw%bwx%bz{%b{|%b}!O%b!O!P%b!P!Q%b!Q![%b![!]%b!^!_%b!_!`%b!`!a%b!a!b%b!b!c%b!c!}%b#Q#R%b#R#S%b#S#T%b#T#o%b#p#q%b#r#s%b~%giV~qr%bst%btu%buv%bvw%bwx%bz{%b{|%b}!O%b!O!P%b!P!Q%b!Q![%b![!]%b!^!_%b!_!`%b!`!a%b!a!b%b!b!c%b!c!}%b#Q#R%b#R#S%b#S#T%b#T#o%b#p#q%b#r#s%b~'ZPT~!]!^'^~'aTO!]'^!]!^'p!^;'S'^;'S;=`(_<%lO'^~'sVOy'^yz(Yz!]'^!]!^'p!^;'S'^;'S;=`(_<%lO'^~(_OQ~~(bP;=`<%l'^~(jOS~~(mQ!Q!R(s!R![*p~(xUY~!O!P)[!Q![*p!g!h){#R#S+U#X#Y){#l#m+[~)aRY~!Q![)j!g!h){#X#Y){~)oSY~!Q![)j!g!h){#R#S*j#X#Y){~*OR{|*X}!O*X!Q![*_~*[P!Q![*_~*dQY~!Q![*_#R#S*X~*mP!Q![)j~*uTY~!O!P)[!Q![*p!g!h){#R#S+U#X#Y){~+XP!Q![*p~+_R!Q![+h!c!i+h#T#Z+h~+mVY~!O!P,S!Q![+h!c!i+h!r!s-P#R#S+[#T#Z+h#d#e-P~,XTY~!Q![,h!c!i,h!r!s-P#T#Z,h#d#e-P~,mUY~!Q![,h!c!i,h!r!s-P#R#S.Q#T#Z,h#d#e-P~-ST{|-c}!O-c!Q![-o!c!i-o#T#Z-o~-fR!Q![-o!c!i-o#T#Z-o~-tSY~!Q![-o!c!i-o#R#S-c#T#Z-o~.TR!Q![,h!c!i,h#T#Z,h~.aP!]!^.d~.iSP~OY.dZ;'S.d;'S;=`.u<%lO.d~.xP;=`<%l.d~/QiX~qr.{st.{tu.{uv.{vw.{wx.{z{.{{|.{}!O.{!O!P.{!P!Q.{!Q![.{![!].{!^!_.{!_!`.{!`!a.{!a!b.{!b!c.{!c!}.{#Q#R.{#R#S.{#S#T.{#T#o.{#p#q.{#r#s.{",tokenizers:[0],topRules:{Module:[0,3]},specialized:[{term:9,get:o=>S[o]||-1}],tokenPrec:0}),i=O.define({name:"wast",parser:Q.configure({props:[s.add({App:P({closing:")",align:!1})}),a.add({App:n,BlockComment(o){return{from:o.from+2,to:o.to-2}}}),t({Keyword:e.keyword,Type:e.typeName,Number:e.number,String:e.string,Identifier:e.variableName,LineComment:e.lineComment,BlockComment:e.blockComment,"( )":e.paren})]}),languageData:{commentTokens:{line:";;",block:{open:"(;",close:";)"}},closeBrackets:{brackets:["(",'"']}}});function p(){return new b(i)}export{p as wast,i as wastLanguage};
|
||||
import{b as O,d as b,L as r,f as s,g as a,s as t,j as P,l as n,t as e}from"./index-7Pb28EN0.js";const S={__proto__:null,anyref:34,dataref:34,eqref:34,externref:34,i31ref:34,funcref:34,i8:34,i16:34,i32:34,i64:34,f32:34,f64:34},Q=r.deserialize({version:14,states:"!^Q]QPOOOqQPO'#CbOOQO'#Cd'#CdOOQO'#Cl'#ClOOQO'#Ch'#ChQ]QPOOOOQO,58|,58|OxQPO,58|OOQO-E6f-E6fOOQO1G.h1G.h",stateData:"!P~O_OSPOSQOS~OTPOVROXROYROZROaQO~OSUO~P]OSXO~P]O",goto:"xaPPPPPPbPbPPPhPPPrXROPTVQTOQVPTWTVXSOPTV",nodeNames:"⚠ LineComment BlockComment Module ) ( App Identifier Type Keyword Number String",maxTerm:17,nodeProps:[["isolate",-3,1,2,11,""],["openedBy",4,"("],["closedBy",5,")"],["group",-6,6,7,8,9,10,11,"Expression"]],skippedNodes:[0,1,2],repeatNodeCount:1,tokenData:"0o~R^XY}YZ}]^}pq}rs!Stu#pxy'Uyz(e{|(j}!O(j!Q!R(s!R![*p!]!^.^#T#o.{~!SO_~~!VVOr!Srs!ls#O!S#O#P!q#P;'S!S;'S;=`#j<%lO!S~!qOZ~~!tRO;'S!S;'S;=`!};=`O!S~#QWOr!Srs!ls#O!S#O#P!q#P;'S!S;'S;=`#j;=`<%l!S<%lO!S~#mP;=`<%l!S~#siqr%bst%btu%buv%bvw%bwx%bz{%b{|%b}!O%b!O!P%b!P!Q%b!Q![%b![!]%b!^!_%b!_!`%b!`!a%b!a!b%b!b!c%b!c!}%b#Q#R%b#R#S%b#S#T%b#T#o%b#p#q%b#r#s%b~%giV~qr%bst%btu%buv%bvw%bwx%bz{%b{|%b}!O%b!O!P%b!P!Q%b!Q![%b![!]%b!^!_%b!_!`%b!`!a%b!a!b%b!b!c%b!c!}%b#Q#R%b#R#S%b#S#T%b#T#o%b#p#q%b#r#s%b~'ZPT~!]!^'^~'aTO!]'^!]!^'p!^;'S'^;'S;=`(_<%lO'^~'sVOy'^yz(Yz!]'^!]!^'p!^;'S'^;'S;=`(_<%lO'^~(_OQ~~(bP;=`<%l'^~(jOS~~(mQ!Q!R(s!R![*p~(xUY~!O!P)[!Q![*p!g!h){#R#S+U#X#Y){#l#m+[~)aRY~!Q![)j!g!h){#X#Y){~)oSY~!Q![)j!g!h){#R#S*j#X#Y){~*OR{|*X}!O*X!Q![*_~*[P!Q![*_~*dQY~!Q![*_#R#S*X~*mP!Q![)j~*uTY~!O!P)[!Q![*p!g!h){#R#S+U#X#Y){~+XP!Q![*p~+_R!Q![+h!c!i+h#T#Z+h~+mVY~!O!P,S!Q![+h!c!i+h!r!s-P#R#S+[#T#Z+h#d#e-P~,XTY~!Q![,h!c!i,h!r!s-P#T#Z,h#d#e-P~,mUY~!Q![,h!c!i,h!r!s-P#R#S.Q#T#Z,h#d#e-P~-ST{|-c}!O-c!Q![-o!c!i-o#T#Z-o~-fR!Q![-o!c!i-o#T#Z-o~-tSY~!Q![-o!c!i-o#R#S-c#T#Z-o~.TR!Q![,h!c!i,h#T#Z,h~.aP!]!^.d~.iSP~OY.dZ;'S.d;'S;=`.u<%lO.d~.xP;=`<%l.d~/QiX~qr.{st.{tu.{uv.{vw.{wx.{z{.{{|.{}!O.{!O!P.{!P!Q.{!Q![.{![!].{!^!_.{!_!`.{!`!a.{!a!b.{!b!c.{!c!}.{#Q#R.{#R#S.{#S#T.{#T#o.{#p#q.{#r#s.{",tokenizers:[0],topRules:{Module:[0,3]},specialized:[{term:9,get:o=>S[o]||-1}],tokenPrec:0}),i=O.define({name:"wast",parser:Q.configure({props:[s.add({App:P({closing:")",align:!1})}),a.add({App:n,BlockComment(o){return{from:o.from+2,to:o.to-2}}}),t({Keyword:e.keyword,Type:e.typeName,Number:e.number,String:e.string,Identifier:e.variableName,LineComment:e.lineComment,BlockComment:e.blockComment,"( )":e.paren})]}),languageData:{commentTokens:{line:";;",block:{open:"(;",close:";)"}},closeBrackets:{brackets:["(",'"']}}});function p(){return new b(i)}export{p as wast,i as wastLanguage};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
web/dist/index.html
vendored
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LoLLMS WebUI</title>
|
||||
<script type="module" crossorigin src="/assets/index-BXY6uktx.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-5mBsl5lX.css">
|
||||
<script type="module" crossorigin src="/assets/index-7Pb28EN0.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CnmZeAO0.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
@ -223,8 +223,6 @@ export default {
|
||||
},
|
||||
getImgUrl() {
|
||||
// Prefer model icon, fallback to default
|
||||
console.log("model icon:")
|
||||
console.log(this.model.icon)
|
||||
return this.model.icon || defaultImgPlaceholder;
|
||||
},
|
||||
defaultImg(event) {
|
||||
|
@ -254,14 +254,17 @@ export default {
|
||||
this.settingsChanged = false;
|
||||
},
|
||||
async saveConfiguration() {
|
||||
this.isLoading = true;
|
||||
this.loading_text = "Saving configuration...";
|
||||
this.isLoading = true;
|
||||
this.loading_text = "Saving configuration...";
|
||||
try {
|
||||
const res = await axios.post('/save_settings', { client_id: this.$store.state.client_id }, { headers: posts_headers });
|
||||
if (res.data.status) this.$store.state.toast.showToast("Settings saved successfully.", 4, true);
|
||||
else this.$store.state.messageBox.showMessage(`Error saving settings: ${res.data.error || 'Error'}`);
|
||||
} catch (error) { this.$store.state.messageBox.showMessage(`Error saving settings: ${error.message}`);
|
||||
} finally { this.isLoading = false; }
|
||||
} finally { this.isLoading = false;
|
||||
this.$store.commit('refreshBindings')
|
||||
this.$store.commit('refreshModelsZoo')
|
||||
}
|
||||
},
|
||||
reset_configuration() {
|
||||
this.$store.state.yesNoDialog.askQuestion("Reset config to default? This deletes current settings.", 'Reset', 'Cancel')
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
<div class="container pt-4 pb-50 mb-50 w-full mx-auto px-4">
|
||||
<TransitionGroup v-if="discussionArr && discussionArr.length > 0" name="list">
|
||||
<!-- Message components remain unchanged -->
|
||||
<Message v-for="msg in discussionArr"
|
||||
:key="msg.id"
|
||||
:message="msg"
|
||||
@ -24,75 +25,63 @@
|
||||
/>
|
||||
</TransitionGroup>
|
||||
|
||||
<div v-if="discussionArr && discussionArr.length < 2 && personality && personality.prompts_list && personality.prompts_list.length > 0" class="w-full rounded-lg m-2 shadow-lg border border-blue-200 dark:border-blue-700 bg-blue-50 dark:bg-blue-900 p-4 pb-2">
|
||||
<h2 class="text-2xl font-bold mb-4 text-blue-700 dark:text-blue-200 border-b border-blue-300 dark:border-blue-600 pb-2">Prompt Examples</h2>
|
||||
<div class="overflow-x-auto flex-grow scrollbar">
|
||||
<div class="flex flex-nowrap gap-4 p-2">
|
||||
<div v-for="(prompt, index) in personality.prompts_list"
|
||||
:title="extractTitle(prompt)"
|
||||
:key="index"
|
||||
@click="handlePromptSelection(prompt)"
|
||||
class="flex-shrink-0 w-[300px] card hover:shadow-xl transition-all duration-300 ease-in-out transform hover:scale-105 flex flex-col justify-between min-h-[200px] group p-4 cursor-pointer">
|
||||
<div class="space-y-2">
|
||||
<h3 class="font-semibold text-lg text-blue-800 dark:text-blue-100 mb-1 truncate" :title="extractTitle(prompt)">
|
||||
{{ extractTitle(prompt) || 'Prompt Example' }}
|
||||
</h3>
|
||||
<div :title="prompt" class="text-sm text-blue-700 dark:text-blue-300 overflow-hidden line-clamp-4 leading-relaxed">
|
||||
{{ getPromptContent(prompt) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 text-xs font-medium link opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||
Click to select
|
||||
</div>
|
||||
<!-- Use the new PromptExamples component -->
|
||||
<PromptExamples
|
||||
v-if="showPromptExamples"
|
||||
:prompts="personality?.prompts_list || []"
|
||||
@prompt-selected="handlePromptSelection"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
<!-- Placeholder Modal (Remains the same) -->
|
||||
<div v-if="showPlaceholderModal" class="fixed inset-0 bg-black bg-opacity-60 dark:bg-opacity-70 flex items-center justify-center z-50 p-4">
|
||||
<!-- Modal Content -->
|
||||
<div class="card max-w-4xl w-full max-h-[90vh] flex flex-col p-0">
|
||||
<h3 class="text-lg font-semibold p-4 border-b border-blue-200 dark:border-blue-700 text-blue-800 dark:text-blue-100">Fill in the placeholders</h3>
|
||||
<div class="flex-1 flex flex-col min-h-0 overflow-hidden p-4 space-y-4">
|
||||
<div class="p-3 bg-blue-100 dark:bg-blue-800 rounded-lg border border-blue-200 dark:border-blue-700">
|
||||
<h4 class="label !mb-1">Live Preview:</h4>
|
||||
<!-- Use the specific content getter for preview -->
|
||||
<div class="flex-1 h-[150px] overflow-y-auto scrollbar bg-white dark:bg-blue-900 p-2 rounded text-sm">
|
||||
<span class="whitespace-pre-wrap text-blue-900 dark:text-blue-100">{{ getPromptContent(previewPrompt) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 overflow-y-auto scrollbar space-y-3 pr-2">
|
||||
<div v-for="(placeholder, index) in parsedPlaceholders" :key="placeholder.fullText" class="flex flex-col">
|
||||
<label :for="'placeholder-'+index" class="label">{{ placeholder.label }}</label>
|
||||
<!-- Input types remain the same -->
|
||||
<input v-if="placeholder.type === 'text'" :id="'placeholder-'+index" v-model="placeholderValues[index]" type="text" class="input" :placeholder="placeholder.label" @input="updatePreview">
|
||||
<input v-if="placeholder.type === 'int'" :id="'placeholder-'+index" v-model.number="placeholderValues[index]" type="number" step="1" class="input" @input="updatePreview">
|
||||
<input v-if="placeholder.type === 'float'" :id="'placeholder-'+index" v-model.number="placeholderValues[index]" type="number" step="0.01" class="input" @input="updatePreview">
|
||||
<textarea v-if="placeholder.type === 'multiline'" :id="'placeholder-'+index" v-model="placeholderValues[index]" rows="4" class="input" @input="updatePreview"></textarea>
|
||||
<div v-if="placeholder.type === 'code'" class="border border-blue-300 dark:border-blue-600 rounded-md overflow-hidden">
|
||||
<div class="bg-blue-200 dark:bg-blue-700 p-1 px-2 text-xs text-blue-700 dark:text-blue-200">{{ placeholder.language || 'Plain text' }}</div>
|
||||
<textarea :id="'placeholder-'+index" v-model="placeholderValues[index]" rows="6" class="w-full p-2 font-mono bg-blue-50 dark:bg-blue-900 border-t border-blue-300 dark:border-blue-600 text-sm" @input="updatePreview"></textarea>
|
||||
</div>
|
||||
<select v-if="placeholder.type === 'options'" :id="'placeholder-'+index" v-model="placeholderValues[index]" class="input" @change="updatePreview">
|
||||
<option value="" disabled>Select an option</option>
|
||||
<option v-for="option in placeholder.options" :key="option" :value="option" class="text-blue-900 dark:text-blue-100 bg-blue-100 dark:bg-blue-800">{{ option }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Placeholder Modal -->
|
||||
<div v-if="showPlaceholderModal" class="fixed inset-0 bg-black bg-opacity-60 dark:bg-opacity-70 flex items-center justify-center z-50 p-4">
|
||||
<div class="card max-w-4xl w-full max-h-[90vh] flex flex-col p-0">
|
||||
<h3 class="text-lg font-semibold p-4 border-b border-blue-200 dark:border-blue-700 text-blue-800 dark:text-blue-100">Fill in the placeholders</h3>
|
||||
<div class="flex-1 flex flex-col min-h-0 overflow-hidden p-4 space-y-4">
|
||||
<div class="p-3 bg-blue-100 dark:bg-blue-800 rounded-lg border border-blue-200 dark:border-blue-700">
|
||||
<h4 class="label !mb-1">Live Preview:</h4>
|
||||
<div class="flex-1 h-[150px] overflow-y-auto scrollbar bg-white dark:bg-blue-900 p-2 rounded text-sm">
|
||||
<span class="whitespace-pre-wrap text-blue-900 dark:text-blue-100">{{ getPromptContent(previewPrompt) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 overflow-y-auto scrollbar space-y-3 pr-2">
|
||||
<div v-for="(placeholder, index) in parsedPlaceholders" :key="placeholder.fullText" class="flex flex-col">
|
||||
<label :for="'placeholder-'+index" class="label">{{ placeholder.label }}</label>
|
||||
<input v-if="placeholder.type === 'text'" :id="'placeholder-'+index" v-model="placeholderValues[index]" type="text" class="input" :placeholder="placeholder.label" @input="updatePreview">
|
||||
<input v-if="placeholder.type === 'int'" :id="'placeholder-'+index" v-model.number="placeholderValues[index]" type="number" step="1" class="input" @input="updatePreview">
|
||||
<input v-if="placeholder.type === 'float'" :id="'placeholder-'+index" v-model.number="placeholderValues[index]" type="number" step="0.01" class="input" @input="updatePreview">
|
||||
<textarea v-if="placeholder.type === 'multiline'" :id="'placeholder-'+index" v-model="placeholderValues[index]" rows="4" class="input" @input="updatePreview"></textarea>
|
||||
<div v-if="placeholder.type === 'code'" class="border border-blue-300 dark:border-blue-600 rounded-md overflow-hidden">
|
||||
<div class="bg-blue-200 dark:bg-blue-700 p-1 px-2 text-xs text-blue-700 dark:text-blue-200">{{ placeholder.language || 'Plain text' }}</div>
|
||||
<textarea :id="'placeholder-'+index" v-model="placeholderValues[index]" rows="6" class="w-full p-2 font-mono bg-blue-50 dark:bg-blue-900 border-t border-blue-300 dark:border-blue-600 text-sm" @input="updatePreview"></textarea>
|
||||
</div>
|
||||
<select v-if="placeholder.type === 'options'" :id="'placeholder-'+index" v-model="placeholderValues[index]" class="input" @change="updatePreview">
|
||||
<option value="" disabled>Select an option</option>
|
||||
<option v-for="option in placeholder.options" :key="option" :value="option" class="text-blue-900 dark:text-blue-100 bg-blue-100 dark:bg-blue-800">{{ option }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 flex justify-end space-x-2 border-t border-blue-200 dark:border-blue-700">
|
||||
<button @click="cancelPlaceholders" class="btn btn-secondary">Cancel</button>
|
||||
<button @click="applyPlaceholders" class="btn btn-primary">Apply</button>
|
||||
</div>
|
||||
<div class="p-4 flex justify-end space-x-2 border-t border-blue-200 dark:border-blue-700">
|
||||
<button @click="cancelPlaceholders" class="btn btn-secondary">Cancel</button>
|
||||
<button @click="applyPlaceholders" class="btn btn-primary">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<WelcomeComponent v-if="!hasActiveDiscussion" />
|
||||
|
||||
<div class="h-40"></div>
|
||||
<div class="h-40"></div> <!-- Padding at the bottom -->
|
||||
</div>
|
||||
|
||||
<!-- Gradient overlay remains the same -->
|
||||
<div class="sticky bottom-0 left-0 right-0 h-48 pointer-events-none bg-gradient-to-t from-blue-100 to-transparent dark:from-blue-900 z-10"></div>
|
||||
</div>
|
||||
|
||||
<!-- ChatBox remains the same -->
|
||||
<div class="sticky bottom-0 left-0 right-0 p-4 z-20 w-full max-w-4xl mx-auto" v-if="hasActiveDiscussion">
|
||||
<ChatBox ref="chatBox"
|
||||
:loading="isGenerating"
|
||||
@ -120,35 +109,29 @@ import { mapState } from 'vuex';
|
||||
import Message from './Message.vue';
|
||||
import ChatBox from './ChatBox.vue';
|
||||
import WelcomeComponent from '@/components/WelcomeComponent.vue';
|
||||
import PromptExamples from './PromptExamples.vue'; // Import the new component
|
||||
import feather from 'feather-icons';
|
||||
|
||||
// Keep parsePlaceholder function here as it's used for the modal
|
||||
const parsePlaceholder = (placeholder) => {
|
||||
const parts = placeholder.replace(/^\[|\]$/g, '').split('::'); // Use regex for cleaner removal
|
||||
const parts = placeholder.replace(/^\[|\]$/g, '').split('::');
|
||||
const label = parts[0];
|
||||
|
||||
if (parts.length === 1) return { label, type: 'text', fullText: placeholder };
|
||||
|
||||
const type = parts[1].toLowerCase(); // Normalize type
|
||||
const type = parts[1].toLowerCase();
|
||||
const result = { label, type, fullText: placeholder };
|
||||
|
||||
switch (type) {
|
||||
case 'int':
|
||||
case 'float':
|
||||
case 'multiline': break; // No extra params needed
|
||||
case 'code':
|
||||
result.language = parts[2] || 'plaintext'; break;
|
||||
case 'options':
|
||||
result.options = parts[2] ? parts[2].split(',').map(o => o.trim()) : []; break;
|
||||
default:
|
||||
result.type = 'text'; // Fallback to text
|
||||
case 'int': case 'float': case 'multiline': break;
|
||||
case 'code': result.language = parts[2] || 'plaintext'; break;
|
||||
case 'options': result.options = parts[2] ? parts[2].split(',').map(o => o.trim()) : []; break;
|
||||
default: result.type = 'text';
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
name: 'ChatArea',
|
||||
components: { Message, ChatBox, WelcomeComponent },
|
||||
// Register the new component
|
||||
components: { Message, ChatBox, WelcomeComponent, PromptExamples },
|
||||
props: {
|
||||
isReady: Boolean,
|
||||
hasActiveDiscussion: Boolean,
|
||||
@ -166,27 +149,35 @@ export default {
|
||||
return {
|
||||
isDragOverChat: false,
|
||||
showPlaceholderModal: false,
|
||||
selectedPrompt: '',
|
||||
placeholders: [],
|
||||
placeholderValues: {},
|
||||
previewPrompt: '',
|
||||
selectedPrompt: '', // The original prompt string with title and placeholders
|
||||
placeholders: [], // Raw placeholder strings like "[placeholder::type]"
|
||||
placeholderValues: {}, // Values entered by the user for placeholders
|
||||
previewPrompt: '', // The prompt string used for live preview in the modal
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['config']),
|
||||
personality() {
|
||||
// Personality computation logic remains the same
|
||||
if (!this.config || !this.config.personalities || this.config.active_personality_id < 0 || this.config.active_personality_id >= this.config.personalities.length) {
|
||||
return null;
|
||||
}
|
||||
const activePersPath = this.config.personalities[this.config.active_personality_id];
|
||||
const basePath = activePersPath?.split(':')[0];
|
||||
// Assuming personalities array is available in the parent or Vuex, passed as a prop or accessed directly if needed
|
||||
// For now, just returning a placeholder object structure if needed, otherwise rely on parent logic
|
||||
// This might need adjustment based on where the full personality details are stored/accessed
|
||||
const fullPersonality = this.$store.state.personalities.find(p => p.full_path === basePath);
|
||||
return fullPersonality || null; // Return the found personality or null
|
||||
// Make sure this logic correctly finds the personality object containing `prompts_list`
|
||||
const fullPersonality = this.$store.state.personalities.find(p => p.full_path === activePersPath);
|
||||
return fullPersonality || { prompts_list: [] }; // Ensure it returns an object, even if empty
|
||||
},
|
||||
parsedPlaceholders() {
|
||||
showPromptExamples() {
|
||||
// Condition to show prompt examples
|
||||
return this.hasActiveDiscussion && // Show only if a discussion exists
|
||||
this.discussionArr &&
|
||||
this.discussionArr.length < 2 && // Show only at the start of a conversation (e.g., 0 or 1 message)
|
||||
this.personality &&
|
||||
this.personality.prompts_list &&
|
||||
this.personality.prompts_list.length > 0;
|
||||
},
|
||||
parsedPlaceholders() {
|
||||
// Logic remains the same
|
||||
const uniqueMap = new Map();
|
||||
this.placeholders.forEach(p => {
|
||||
const parsed = parsePlaceholder(p);
|
||||
@ -196,17 +187,19 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// Methods like getAvatar, scrollToBottom, handleDrop, handleFilesDropped remain the same
|
||||
getAvatar(sender) {
|
||||
if (!this.config || !sender) return null;
|
||||
const senderLower = sender.toLowerCase().trim();
|
||||
const userLower = this.config.user_name?.toLowerCase().trim();
|
||||
if (!this.config || !sender) return null;
|
||||
const senderLower = sender.toLowerCase().trim();
|
||||
const userLower = this.config.user_name?.toLowerCase().trim();
|
||||
|
||||
if (senderLower === userLower) {
|
||||
return this.config.user_avatar ? `user_infos/${this.config.user_avatar}` : null; // Handle missing user avatar
|
||||
}
|
||||
if (senderLower === userLower) {
|
||||
return this.config.user_avatar ? `user_infos/${this.config.user_avatar}` : null;
|
||||
}
|
||||
|
||||
const personality = this.personalityAvatars.find(p => p.name?.toLowerCase().trim() === senderLower);
|
||||
return personality?.avatar ? `/${personality.avatar}` : null; // Prepend '/' for web path
|
||||
// Assuming personalityAvatars is correctly populated [{ name: 'PersonalityName', avatar: 'path/to/avatar.png' }, ...]
|
||||
const personality = this.personalityAvatars.find(p => p.name?.toLowerCase().trim() === senderLower);
|
||||
return personality?.avatar ? `/${personality.avatar}` : null; // Ensure leading slash if needed
|
||||
},
|
||||
scrollToBottom() {
|
||||
nextTick(() => {
|
||||
@ -224,86 +217,103 @@ export default {
|
||||
handleFilesDropped(files) {
|
||||
this.$emit('files-dropped', files);
|
||||
},
|
||||
extractTitle(prompt) {
|
||||
const titleMatch = prompt.match(/@<(.*?)>@/);
|
||||
return titleMatch ? titleMatch[1] : null;
|
||||
},
|
||||
|
||||
// --- Placeholder and Prompt Handling Logic ---
|
||||
|
||||
// Utility to get content part of the prompt (without title tag)
|
||||
getPromptContent(prompt) {
|
||||
if (!prompt) return '';
|
||||
return prompt.replace(/@<.*?>@/, '').trim();
|
||||
},
|
||||
|
||||
// Triggered by the 'prompt-selected' event from PromptExamples component
|
||||
handlePromptSelection(prompt) {
|
||||
this.selectedPrompt = prompt;
|
||||
this.previewPrompt = this.getPromptContent(prompt); // Use content for preview initially
|
||||
this.selectedPrompt = prompt; // Store the full original prompt
|
||||
this.previewPrompt = prompt; // Initialize preview with the full prompt (will be updated)
|
||||
this.placeholders = this.extractPlaceholders(prompt);
|
||||
|
||||
if (this.placeholders.length > 0) {
|
||||
this.placeholderValues = {}; // Reset values
|
||||
this.parsedPlaceholders.forEach((ph, index) => {
|
||||
// Pre-fill with default values if any are defined in the placeholder syntax (future enhancement)
|
||||
this.placeholderValues[index] = ''; // Initialize as empty
|
||||
});
|
||||
this.showPlaceholderModal = true;
|
||||
this.updatePreview(); // Initial preview update
|
||||
} else {
|
||||
// If no placeholders, directly use the content part of the prompt
|
||||
this.setPromptInChatbox(this.getPromptContent(prompt));
|
||||
}
|
||||
},
|
||||
|
||||
extractPlaceholders(prompt) {
|
||||
// Extracts placeholders like [placeholder::type] or [placeholder]
|
||||
const placeholderRegex = /\[(.*?)\]/g;
|
||||
// Avoid duplicates if the same placeholder appears multiple times
|
||||
const uniquePlaceholders = new Set([...prompt.matchAll(placeholderRegex)].map(match => match[0]));
|
||||
const uniquePlaceholders = new Set([...(prompt || '').matchAll(placeholderRegex)].map(match => match[0]));
|
||||
return Array.from(uniquePlaceholders);
|
||||
},
|
||||
|
||||
updatePreview() {
|
||||
let preview = this.selectedPrompt;
|
||||
let preview = this.selectedPrompt; // Start with the original prompt
|
||||
this.parsedPlaceholders.forEach((placeholder, index) => {
|
||||
const value = this.placeholderValues[index];
|
||||
// Replace all occurrences of the same placeholder using RegExp
|
||||
const regex = new RegExp(this.escapeRegExp(placeholder.fullText), 'g');
|
||||
// Use the original full placeholder text if the value is empty, otherwise use the value
|
||||
// Replace placeholder with value, or keep original placeholder if value is empty
|
||||
preview = preview.replace(regex, value || placeholder.fullText);
|
||||
});
|
||||
this.previewPrompt = preview; // Update the preview reactive property
|
||||
this.previewPrompt = preview; // Update the reactive preview property
|
||||
},
|
||||
|
||||
escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
},
|
||||
|
||||
cancelPlaceholders() {
|
||||
this.showPlaceholderModal = false;
|
||||
// Resetting state is handled in handlePromptSelection if re-opened
|
||||
// No need to reset here, state will be reset if another prompt is selected
|
||||
},
|
||||
|
||||
applyPlaceholders() {
|
||||
let finalPrompt = this.selectedPrompt;
|
||||
let finalPromptWithValues = this.selectedPrompt; // Start with original
|
||||
this.parsedPlaceholders.forEach((placeholder, index) => {
|
||||
const value = this.placeholderValues[index];
|
||||
if (value !== undefined && value !== '') { // Apply only if a value is provided
|
||||
// Only replace if a value is actually provided
|
||||
if (value !== undefined && value !== null && value !== '') {
|
||||
const regex = new RegExp(this.escapeRegExp(placeholder.fullText), 'g');
|
||||
finalPrompt = finalPrompt.replace(regex, value);
|
||||
finalPromptWithValues = finalPromptWithValues.replace(regex, value);
|
||||
}
|
||||
// If value is empty, the original placeholder might remain.
|
||||
});
|
||||
|
||||
// Now, remove any remaining placeholder syntax *and* the title tag for the final chatbox input
|
||||
const finalContent = this.getPromptContent(finalPromptWithValues) // Remove title tag first
|
||||
.replace(/\[(.*?)\]/g, ''); // Remove any remaining empty/unfilled placeholder brackets
|
||||
|
||||
this.showPlaceholderModal = false;
|
||||
this.setPromptInChatbox(this.getPromptContent(finalPrompt)); // Use the final processed prompt content
|
||||
this.setPromptInChatbox(finalContent.trim()); // Set the processed content in the chatbox
|
||||
},
|
||||
setPromptInChatbox(prompt) {
|
||||
|
||||
setPromptInChatbox(promptContent) {
|
||||
if (this.$refs.chatBox) {
|
||||
this.$refs.chatBox.message = prompt;
|
||||
// Optionally focus the input
|
||||
this.$refs.chatBox.focusInput();
|
||||
this.$refs.chatBox.message = promptContent;
|
||||
this.$refs.chatBox.focusInput(); // Optional: focus the input
|
||||
}
|
||||
},
|
||||
|
||||
// --- End Placeholder Logic ---
|
||||
},
|
||||
watch: {
|
||||
// Watchers remain the same
|
||||
discussionArr: {
|
||||
handler() {
|
||||
this.scrollToBottom();
|
||||
this.$nextTick(() => feather.replace());
|
||||
//this.scrollToBottom();
|
||||
this.$nextTick(() => feather.replace());
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
personality: {
|
||||
handler(newVal, oldVal) {
|
||||
// Reset prompt example state if personality changes
|
||||
if (newVal?.full_path !== oldVal?.full_path) {
|
||||
// Reset placeholder state if personality changes
|
||||
this.showPlaceholderModal = false;
|
||||
this.selectedPrompt = '';
|
||||
this.placeholders = [];
|
||||
@ -315,12 +325,14 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.scrollToBottom();
|
||||
// Mounted logic remains the same
|
||||
// this.scrollToBottom();
|
||||
nextTick(() => {
|
||||
feather.replace();
|
||||
});
|
||||
},
|
||||
updated() {
|
||||
// Updated logic remains the same
|
||||
nextTick(() => {
|
||||
feather.replace();
|
||||
});
|
||||
@ -329,5 +341,11 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
/* Scoped styles for ChatArea remain unchanged */
|
||||
.pb-50 { /* Ensure enough padding at the bottom inside the scrollable area */
|
||||
padding-bottom: 50px; /* Adjust as needed */
|
||||
}
|
||||
.mb-50 { /* Ensure enough margin at the bottom inside the scrollable area if using margin instead */
|
||||
margin-bottom: 50px; /* Adjust as needed */
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user