teodor-new-chat-ui 1.2.0 → 1.2.1
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/dist/index.esm.js +1 -1
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -28,7 +28,7 @@ function ue(e) {
|
|
|
28
28
|
let r = e;
|
|
29
29
|
for (const n of t)
|
|
30
30
|
r = r.replace(n, "");
|
|
31
|
-
return r.replace(
|
|
31
|
+
return r.replace(/</g, "<").replace(/>/g, ">").trim();
|
|
32
32
|
}
|
|
33
33
|
function In(e, t = rr) {
|
|
34
34
|
if (!e || typeof e != "string")
|
package/dist/index.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(O,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react"),require("lucide-react"),require("@radix-ui/react-slot"),require("class-variance-authority"),require("clsx"),require("tailwind-merge"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","lucide-react","@radix-ui/react-slot","class-variance-authority","clsx","tailwind-merge","react-dom"],a):(O=typeof globalThis<"u"?globalThis:O||self,a(O.NewChatUI={},O.jsxRuntime,O.React,O.LucideReact,O.reactSlot,O.classVarianceAuthority,O.clsx,O.tailwindMerge,O.ReactDOM))})(this,function(O,a,L,W,Ze,Tt,un,hn,pn){"use strict";function Nt(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const u=Nt(L),Pt=Nt(pn),Qe=1e4,Re=200,At=/^[a-zA-Z0-9\-_]{1,50}$/;function gn(e){return typeof e!="string"?String(e):e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/").trim()}function ae(e){if(typeof e!="string")return String(e);const t=[/<script[^>]*>.*?<\/script>/gi,/<iframe[^>]*>.*?<\/iframe>/gi,/javascript:/gi,/vbscript:/gi,/on\w+\s*=/gi,/<object[^>]*>.*?<\/object>/gi,/<embed[^>]*>.*?<\/embed>/gi,/<form[^>]*>.*?<\/form>/gi];let r=e;for(const n of t)r=r.replace(n,"");return r.replace(
|
|
1
|
+
(function(O,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react"),require("lucide-react"),require("@radix-ui/react-slot"),require("class-variance-authority"),require("clsx"),require("tailwind-merge"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","lucide-react","@radix-ui/react-slot","class-variance-authority","clsx","tailwind-merge","react-dom"],a):(O=typeof globalThis<"u"?globalThis:O||self,a(O.NewChatUI={},O.jsxRuntime,O.React,O.LucideReact,O.reactSlot,O.classVarianceAuthority,O.clsx,O.tailwindMerge,O.ReactDOM))})(this,function(O,a,L,W,Ze,Tt,un,hn,pn){"use strict";function Nt(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const u=Nt(L),Pt=Nt(pn),Qe=1e4,Re=200,At=/^[a-zA-Z0-9\-_]{1,50}$/;function gn(e){return typeof e!="string"?String(e):e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/").trim()}function ae(e){if(typeof e!="string")return String(e);const t=[/<script[^>]*>.*?<\/script>/gi,/<iframe[^>]*>.*?<\/iframe>/gi,/javascript:/gi,/vbscript:/gi,/on\w+\s*=/gi,/<object[^>]*>.*?<\/object>/gi,/<embed[^>]*>.*?<\/embed>/gi,/<form[^>]*>.*?<\/form>/gi];let r=e;for(const n of t)r=r.replace(n,"");return r.replace(/</g,"<").replace(/>/g,">").trim()}function Ot(e,t=Qe){if(!e||typeof e!="string")throw new Error("Invalid content: must be a non-empty string");if(e.length>t)throw new Error(`Message exceeds maximum length of ${t} characters`);return e}function mn(e){if(!e||typeof e!="string")throw new Error("Invalid thread ID: must be a non-empty string");if(!At.test(e))throw new Error("Invalid thread ID: contains invalid characters");return e}function Se(e){let t;return typeof e=="string"?t=e:typeof e=="object"&&e!==null?t=JSON.stringify(e):t=String(e),Ot(t),ae(t)}function vn(e){if(!e||typeof e!="string")throw new Error("Invalid title: must be a non-empty string");if(e.length>Re)throw new Error(`Title exceeds maximum length of ${Re} characters`);return ae(e)}function wn(e){try{const t=JSON.parse(e);if(typeof t=="object"&&t!==null){const r=["__proto__","constructor","prototype"];for(const n of r)if(n in t)throw new Error(`Dangerous property detected: ${n}`)}return t}catch(t){throw new Error(`Invalid JSON: ${t instanceof Error?t.message:"Unknown error"}`)}}function bn(e,t){return(...r)=>(typeof r[0]=="string"&&(r[0]=t(r[0])),e(...r))}const Lt=L.createContext(null),yn="http://localhost:8000/api/chat";function Le({children:e,apiBaseUrl:t=yn,enableUrlSync:r=!1,getAuthHeaders:n,authToken:o}){const[s,i]=L.useState({currentThreadId:null,messages:[],isLoading:!1,isLoadingHistory:!1,error:null,interrupt:null,threads:[],loadingThreads:!1,availableBranches:[],currentBranch:null}),l=L.useCallback(()=>r?new URLSearchParams(window.location.search).get("thread"):null,[r]),f=L.useCallback(x=>{if(!r)return;const b=new URL(window.location.href);x?b.searchParams.set("thread",x):b.searchParams.delete("thread"),window.history.pushState({},"",b.toString())},[r]);L.useEffect(()=>{if(r){const x=l();x&&i(b=>({...b,currentThreadId:x}))}},[r,l]),L.useEffect(()=>{if(!r)return;const x=()=>{const b=l();i(A=>({...A,currentThreadId:b}))};return window.addEventListener("popstate",x),()=>window.removeEventListener("popstate",x)},[r,l]);const c=L.useCallback((x={})=>{const b={"Content-Type":"application/json",...x};if(n)return{...b,...n()};if(o)return{...b,Authorization:`Bearer ${o}`};const A=localStorage.getItem("authToken");return A?{...b,Authorization:`Bearer ${A}`}:b},[n,o]),d=L.useCallback(async()=>{i(x=>({...x,loadingThreads:!0}));try{const x=await fetch(`${t}/threads`,{headers:c()});if(!x.ok)throw new Error("Failed to load threads");const b=await x.json();i(A=>({...A,threads:b,loadingThreads:!1}))}catch(x){i(b=>({...b,loadingThreads:!1,error:x instanceof Error?x.message:"Failed to load threads"}))}},[t,c]),h=x=>x.map(b=>({id:b.id,role:b.role==="human"?"human":b.role==="ai"?"ai":"tool",content:b.content,timestamp:b.timestamp,name:b.name,tool_call_id:b.tool_call_id,args:b.args,branch_id:b.branch_id,sequence_number:b.sequence_number})),p=L.useCallback(async x=>{i(b=>({...b,isLoadingHistory:!0}));try{const b=await fetch(`${t}/history/${x}`,{headers:c()});if(!b.ok)throw new Error("Failed to load history");const A=await b.json(),D=h(A);i(F=>({...F,messages:D,isLoadingHistory:!1}))}catch(b){i(A=>({...A,isLoadingHistory:!1,error:b instanceof Error?b.message:"Failed to load history"}))}},[t,c]),g=L.useCallback(async x=>{try{const b=await fetch(`${t}/threads/${x}/branches`,{headers:c()});if(!b.ok)return;const A=await b.json();i(D=>({...D,availableBranches:A.branches||[],currentBranch:A.current_branch}))}catch(b){console.warn("Failed to load branches:",b)}},[t,c]),v=L.useCallback(x=>{i(b=>({...b,currentThreadId:x,messages:[],availableBranches:[],currentBranch:null,error:null})),f(x),x&&Promise.all([p(x),g(x)]).catch(b=>{console.error("Failed to load thread data:",b)})},[f,p,g]),y=L.useCallback(async()=>{try{const x=await fetch(`${t}/threads`,{method:"POST",headers:c()});if(!x.ok)throw new Error("Failed to create thread");const A=(await x.json()).thread_id;return await d(),A}catch(x){throw i(b=>({...b,error:x instanceof Error?x.message:"Failed to create thread"})),x}},[t,c,d]),C=L.useCallback(async x=>{console.log("deleteThread called with threadId:",x),console.log("apiBaseUrl:",t);try{const b=`${t}/threads/${x}`;console.log("Making DELETE request to:",b);const A=await fetch(b,{method:"DELETE",headers:c()});if(console.log("Delete response status:",A.status),console.log("Delete response ok:",A.ok),!A.ok){const D=await A.text();throw console.log("Delete error response:",D),new Error(`Failed to delete thread: ${A.status} ${D}`)}console.log("Thread deleted successfully"),s.currentThreadId===x&&(console.log("Clearing current thread as it was deleted"),v(null)),console.log("Reloading threads list"),await d()}catch(b){console.error("Error deleting thread:",b),i(A=>({...A,error:b instanceof Error?b.message:"Failed to delete thread"}))}},[t,s.currentThreadId,v,d,c]),S=L.useCallback(async(x,b)=>{try{if(!(await fetch(`${t}/threads/${x}/title`,{method:"PATCH",headers:c(),body:JSON.stringify({title:b})})).ok)throw new Error("Failed to update thread title");await d()}catch(A){i(D=>({...D,error:A instanceof Error?A.message:"Failed to update thread title"}))}},[t,d,c]),E=L.useCallback(async x=>{if(s.currentThreadId)try{const b=Se(x),A={id:`temp-${Date.now()}`,role:"human",content:b,timestamp:new Date().toISOString()};i(D=>({...D,messages:[...D.messages,A],isLoading:!0,error:null}));try{const D=await fetch(`${t}/stream`,{method:"POST",headers:c(),body:JSON.stringify({thread_id:s.currentThreadId,messages:[...s.messages,{role:"human",content:b}],operation:"continue"})});if(!D.ok){const F=await D.text();throw new Error(`HTTP ${D.status}: ${F}`)}await P(D),await p(s.currentThreadId)}catch(D){i(F=>({...F,messages:F.messages.filter(N=>N.id!==A.id),isLoading:!1,error:D instanceof Error?D.message:"Failed to send message"}))}}catch(b){i(A=>({...A,error:b instanceof Error?b.message:"Invalid message content"}))}},[t,s.currentThreadId,s.messages,p,c]),P=async x=>{var F;const b=(F=x.body)==null?void 0:F.getReader();if(!b){i(N=>({...N,isLoading:!1}));return}const A=new TextDecoder;let D="";try{for(;;){const{done:N,value:H}=await b.read();if(N)break;D+=A.decode(H,{stream:!0});const M=D.split(`
|
|
2
2
|
`);D=M.pop()||"";for(const B of M)if(B.trim()&&B.startsWith("data: "))try{const $=JSON.parse(B.slice(6));$.type==="text"?i(Y=>{const Ce=[...Y.messages],Ae=Ce[Ce.length-1];return Ae&&Ae.role==="ai"?Ae.content+=$.text:Ce.push({id:`ai-${Date.now()}`,role:"ai",content:$.text,timestamp:new Date().toISOString()}),{...Y,messages:Ce}}):$.type==="tool_call"?i(Y=>({...Y,messages:[...Y.messages,{id:`tool-${Date.now()}`,role:"tool",content:$.result||"",name:$.name||"unknown_function",tool_call_id:$.id,args:$.args,timestamp:new Date().toISOString()}]})):$.type==="complete"&&i(Y=>({...Y,isLoading:!1}))}catch($){console.warn("Failed to parse streaming data:",B,$)}}}catch(N){console.error("Streaming error:",N)}finally{i(N=>({...N,isLoading:!1}))}};L.useEffect(()=>{d()},[d]);const m=L.useCallback(async(x,b,A=!1)=>{if(!(!s.currentThreadId||!x.id)){i(D=>({...D,isLoading:!0,error:null}));try{const D=b?A?"edit_from_input":"edit_and_regenerate":"regenerate",F=await fetch(`${t}/stream`,{method:"POST",headers:c(),body:JSON.stringify({thread_id:s.currentThreadId,messages:s.messages,operation:D,from_message_id:x.id,edited_content:b,create_branch:!!b})});if(!F.ok){const N=await F.text();throw new Error(`HTTP ${F.status}: ${N}`)}await P(F),await Promise.all([p(s.currentThreadId),g(s.currentThreadId)])}catch(D){i(F=>({...F,isLoading:!1,error:D instanceof Error?D.message:"Failed to regenerate message"}))}}},[t,s.currentThreadId,s.messages,p,g,c]),w=L.useCallback(async(x,b,A=!1,D=!1)=>{if(!(!s.currentThreadId||!x.id)){if(A){await m(x,b,D);return}i(F=>({...F,messages:F.messages.map(N=>N.id===x.id?{...N,content:b}:N)}))}},[s.currentThreadId,m]),_=L.useCallback(async x=>{if(s.currentThreadId)try{if(!(await fetch(`${t}/threads/${s.currentThreadId}/branch`,{method:"PATCH",headers:c(),body:JSON.stringify({branch_id:x})})).ok)throw new Error("Failed to switch branch");i(A=>({...A,currentBranch:x})),await p(s.currentThreadId)}catch(b){i(A=>({...A,error:b instanceof Error?b.message:"Failed to switch branch"}))}},[t,s.currentThreadId,p,c]),T=L.useCallback(()=>{i(x=>({...x,isLoading:!1}))},[]),k=L.useCallback(()=>{i(x=>({...x,error:null}))},[]),I=L.useCallback(async()=>{await d(),s.currentThreadId&&await Promise.all([p(s.currentThreadId),g(s.currentThreadId)])},[d,p,g,s.currentThreadId]),z={...s,selectThread:v,createThread:y,deleteThread:C,updateThreadTitle:S,sendMessage:E,editMessage:w,regenerateFromMessage:m,stop:T,switchBranch:_,clearError:k,refresh:I};return a.jsx(Lt.Provider,{value:z,children:e})}function fe(){const e=L.useContext(Lt);if(!e)throw new Error("useChat must be used within a ChatProvider");return e}function X(...e){return hn.twMerge(un.clsx(e))}const xn=Tt.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),j=u.forwardRef(({className:e,variant:t,size:r,asChild:n=!1,...o},s)=>{const i=n?Ze.Slot:"button";return a.jsx(i,{className:X(xn({variant:t,size:r,className:e})),ref:s,...o})});j.displayName="Button";const _e=u.forwardRef(({className:e,...t},r)=>a.jsx("textarea",{className:X("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",e),ref:r,...t}));_e.displayName="Textarea";function et({message:e,onRegenerate:t,onEditMessage:r,showRegenerate:n=!1,showBranches:o=!1,branches:s=[],onSwitchBranch:i}){var P;const[l,f]=L.useState(!1),[c,d]=L.useState(!1),[h,p]=L.useState(typeof e.content=="string"?e.content:JSON.stringify(e.content)),g=()=>{t&&t(e)},v=()=>{try{const m=typeof e.content=="string"?e.content:JSON.stringify(e.content),w=Se(h);w.trim()&&w!==m&&r&&r(e,w.trim(),!0)}catch(m){console.error("Error validating edit content:",m)}d(!1)},y=()=>{const m=typeof e.content=="string"?e.content:JSON.stringify(e.content);p(m),d(!1)},C=()=>{switch(e.role){case"human":return a.jsx(W.User,{size:20,className:"text-blue-600"});case"ai":return a.jsx(W.Bot,{size:20,className:"text-green-600"});case"tool":return a.jsx(W.Wrench,{size:20,className:"text-orange-600"});default:return a.jsx(W.Bot,{size:20,className:"text-gray-600"})}},S=()=>{switch(e.role){case"human":return"You";case"ai":return"Assistant";case"tool":return e.name||"Tool";default:return"Message"}},E=()=>{try{return typeof e.content=="string"?ae(e.content):e.role==="tool"&&e.args?ae(JSON.stringify(e.args,null,2)):ae(JSON.stringify(e.content,null,2))}catch(m){return console.warn("Error formatting message content:",m),"[Content formatting error]"}};return console.log("Rendering message:",e),e.role==="human"?a.jsxs("div",{className:"flex gap-3 justify-end mb-4",children:[a.jsxs("div",{className:"max-w-[80%] rounded-lg p-4 relative group",style:{backgroundColor:"#2563eb",color:"white",border:"2px solid #1d4ed8",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)"},children:[e.id&&r&&a.jsx("div",{className:"absolute -top-1 -right-1 flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity",children:c?a.jsxs(a.Fragment,{children:[a.jsx(j,{size:"sm",variant:"ghost",onClick:v,className:"h-6 w-6 p-0 bg-white/10 hover:bg-white/20",title:"Save changes and regenerate",children:a.jsx(W.Check,{className:"h-3 w-3"})}),a.jsx(j,{size:"sm",variant:"ghost",onClick:y,className:"h-6 w-6 p-0 bg-white/10 hover:bg-white/20",title:"Cancel editing",children:a.jsx(W.X,{className:"h-3 w-3"})})]}):a.jsx(j,{size:"sm",variant:"ghost",onClick:()=>{const m=typeof e.content=="string"?e.content:JSON.stringify(e.content);r(e,m,!1,!0)},className:"h-6 w-6 p-0 bg-white/10 hover:bg-white/20",title:"Edit message in input field and create branch",children:a.jsx(W.Edit2,{className:"h-3 w-3"})})}),a.jsx("div",{className:"whitespace-pre-wrap",style:{color:"white"},children:c?a.jsx(_e,{value:h,onChange:m=>p(m.target.value),className:"w-full min-h-[60px] bg-white/10 border-white/20 text-white placeholder-white/70",placeholder:"Edit your message...",autoFocus:!0}):a.jsx("span",{style:{color:"white"},children:ae(((P=e.content)==null?void 0:P.toString())||"[No content]")})}),e.timestamp&&!c&&a.jsx("div",{className:"text-xs opacity-70 mt-2",style:{color:"white"},children:new Date(e.timestamp).toLocaleTimeString()})]}),a.jsx("div",{className:"flex-shrink-0 w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center",children:C()})]}):a.jsxs("div",{className:"flex gap-3 justify-start mb-4",children:[a.jsx("div",{className:"flex-shrink-0 w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center",children:C()}),a.jsxs("div",{className:`
|
|
3
3
|
max-w-[80%] rounded-lg p-3 relative group
|
|
4
4
|
${e.role==="tool"?"bg-orange-50 border border-orange-200":"bg-gray-100 text-gray-900"}
|
package/package.json
CHANGED