@miiflow/assistant-ui 0.2.3 → 0.3.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/dist/{WelcomeScreen-YsXZsAwZ.d.ts → WelcomeScreen-DAa22X9b.d.ts} +1 -1
- package/dist/{chunk-POKFMILU.js → chunk-IM4WITWJ.js} +9 -11
- package/dist/chunk-IM4WITWJ.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styled/index.d.ts +1 -1
- package/dist/styled/index.js +1 -1
- package/dist/styles-no-preflight.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +9 -18
- package/dist/WelcomeScreen-BiY3uGhp.d.cts +0 -301
- package/dist/avatar-CL1hlGO5.d.cts +0 -109
- package/dist/branding-SzYU4ncD.d.cts +0 -18
- package/dist/chunk-3SEVU272.cjs +0 -2
- package/dist/chunk-3SEVU272.cjs.map +0 -1
- package/dist/chunk-HVCCZKEO.cjs +0 -2
- package/dist/chunk-HVCCZKEO.cjs.map +0 -1
- package/dist/chunk-KSMAVBLY.cjs +0 -2
- package/dist/chunk-KSMAVBLY.cjs.map +0 -1
- package/dist/chunk-POKFMILU.js.map +0 -1
- package/dist/chunk-QGRXQAWZ.cjs +0 -22
- package/dist/chunk-QGRXQAWZ.cjs.map +0 -1
- package/dist/chunk-SFEPMZCU.cjs +0 -2
- package/dist/chunk-SFEPMZCU.cjs.map +0 -1
- package/dist/chunk-TOYU46SZ.cjs +0 -2
- package/dist/chunk-TOYU46SZ.cjs.map +0 -1
- package/dist/chunk-ZKMXEECD.cjs +0 -2
- package/dist/chunk-ZKMXEECD.cjs.map +0 -1
- package/dist/client/index.cjs +0 -9
- package/dist/client/index.cjs.map +0 -1
- package/dist/client/index.d.cts +0 -249
- package/dist/context/index.cjs +0 -2
- package/dist/context/index.cjs.map +0 -1
- package/dist/context/index.d.cts +0 -43
- package/dist/hooks/index.cjs +0 -2
- package/dist/hooks/index.cjs.map +0 -1
- package/dist/hooks/index.d.cts +0 -146
- package/dist/index.cjs +0 -2
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -157
- package/dist/message-9z0crkf9.d.cts +0 -88
- package/dist/primitives/index.cjs +0 -2
- package/dist/primitives/index.cjs.map +0 -1
- package/dist/primitives/index.d.cts +0 -91
- package/dist/streaming-CF63E6iS.d.cts +0 -426
- package/dist/styled/index.cjs +0 -2
- package/dist/styled/index.cjs.map +0 -1
- package/dist/styled/index.d.cts +0 -477
package/dist/chunk-SFEPMZCU.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var e=react.createContext(null);function P({children:t,messages:o,isStreaming:n=false,streamingMessageId:a=null,viewerRole:i="user",onSendMessage:r,onStopStreaming:s,onRetryLastMessage:l,customData:C,onVisualizationAction:u}){let c=react.useCallback(async(h,v)=>{await r(h,v);},[r]),d=react.useMemo(()=>({messages:o,isStreaming:n,streamingMessageId:a,viewerRole:i,sendMessage:c,stopStreaming:s,retryLastMessage:l,customData:C,onVisualizationAction:u}),[o,n,a,i,c,s,l,C,u]);return jsxRuntime.jsx(e.Provider,{value:d,children:t})}function f(){let t=react.useContext(e);if(!t)throw new Error("useChatContext must be used within a ChatProvider");return t}exports.a=e;exports.b=P;exports.c=f;//# sourceMappingURL=chunk-SFEPMZCU.cjs.map
|
|
2
|
-
//# sourceMappingURL=chunk-SFEPMZCU.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/ChatProvider.tsx"],"names":["ChatContext","createContext","ChatProvider","children","messages","isStreaming","streamingMessageId","viewerRole","onSendMessage","onStopStreaming","onRetryLastMessage","customData","onVisualizationAction","sendMessage","useCallback","content","attachments","value","useMemo","jsx","useChatContext","context","useContext"],"mappings":"gFA8BA,IAAMA,CAAAA,CAAcC,mBAAAA,CAAuC,IAAI,EAexD,SAASC,CAAAA,CAAa,CAC3B,QAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CAAc,KAAA,CACd,kBAAA,CAAAC,CAAAA,CAAqB,IAAA,CACrB,UAAA,CAAAC,CAAAA,CAAa,MAAA,CACb,aAAA,CAAAC,CAAAA,CACA,eAAA,CAAAC,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,qBAAA,CAAAC,CACF,CAAA,CAAsB,CACpB,IAAMC,CAAAA,CAAcC,iBAAAA,CAClB,MAAOC,CAAAA,CAAiBC,CAAAA,GAAyB,CAC/C,MAAMR,CAAAA,CAAcO,CAAAA,CAASC,CAAW,EAC1C,CAAA,CACA,CAACR,CAAa,CAChB,CAAA,CAEMS,CAAAA,CAAQC,aAAAA,CACZ,KAAO,CACL,QAAA,CAAAd,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,WAAA,CAAAM,CAAAA,CACA,aAAA,CAAeJ,CAAAA,CACf,gBAAA,CAAkBC,CAAAA,CAClB,UAAA,CAAAC,CAAAA,CACA,qBAAA,CAAAC,CACF,CAAA,CAAA,CACA,CACER,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAM,CAAAA,CACAJ,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CACF,CACF,CAAA,CAEA,OAAOO,cAAAA,CAACnB,CAAAA,CAAY,QAAA,CAAZ,CAAqB,KAAA,CAAOiB,CAAAA,CAAQ,QAAA,CAAAd,CAAAA,CAAS,CACvD,CAEO,SAASiB,CAAAA,EAAiB,CAC/B,IAAMC,CAAAA,CAAUC,gBAAAA,CAAWtB,CAAW,CAAA,CACtC,GAAI,CAACqB,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,mDAAmD,CAAA,CAErE,OAAOA,CACT","file":"chunk-SFEPMZCU.cjs","sourcesContent":["import {\n createContext,\n useContext,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport type { ChatMessage, ParticipantRole, VisualizationActionEvent } from \"../types\";\n\nexport interface ChatContextValue {\n /** List of messages in the conversation */\n messages: ChatMessage[];\n /** Whether a message is currently being streamed */\n isStreaming: boolean;\n /** ID of the message currently being streamed */\n streamingMessageId: string | null;\n /** The viewer's role (determines message alignment) */\n viewerRole: ParticipantRole;\n /** Send a new message */\n sendMessage: (content: string, attachments?: File[]) => Promise<void>;\n /** Stop the current streaming response */\n stopStreaming?: () => void;\n /** Retry the last failed message */\n retryLastMessage?: () => Promise<void>;\n /** Custom data passed through context */\n customData?: Record<string, unknown>;\n /** Callback when user interacts with a visualization (form submit, card action, etc.) */\n onVisualizationAction?: (event: VisualizationActionEvent) => void;\n}\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\nexport interface ChatProviderProps {\n children: ReactNode;\n messages: ChatMessage[];\n isStreaming?: boolean;\n streamingMessageId?: string | null;\n viewerRole?: ParticipantRole;\n onSendMessage: (content: string, attachments?: File[]) => Promise<void>;\n onStopStreaming?: () => void;\n onRetryLastMessage?: () => Promise<void>;\n customData?: Record<string, unknown>;\n onVisualizationAction?: (event: VisualizationActionEvent) => void;\n}\n\nexport function ChatProvider({\n children,\n messages,\n isStreaming = false,\n streamingMessageId = null,\n viewerRole = \"user\",\n onSendMessage,\n onStopStreaming,\n onRetryLastMessage,\n customData,\n onVisualizationAction,\n}: ChatProviderProps) {\n const sendMessage = useCallback(\n async (content: string, attachments?: File[]) => {\n await onSendMessage(content, attachments);\n },\n [onSendMessage]\n );\n\n const value = useMemo<ChatContextValue>(\n () => ({\n messages,\n isStreaming,\n streamingMessageId,\n viewerRole,\n sendMessage,\n stopStreaming: onStopStreaming,\n retryLastMessage: onRetryLastMessage,\n customData,\n onVisualizationAction,\n }),\n [\n messages,\n isStreaming,\n streamingMessageId,\n viewerRole,\n sendMessage,\n onStopStreaming,\n onRetryLastMessage,\n customData,\n onVisualizationAction,\n ]\n );\n\n return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;\n}\n\nexport function useChatContext() {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error(\"useChatContext must be used within a ChatProvider\");\n }\n return context;\n}\n\nexport { ChatContext };\n"]}
|
package/dist/chunk-TOYU46SZ.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use strict';var react=require('react');function L({enabled:s=true,smooth:h=true,scrollToBottomOnMount:T=true}={}){let o=react.useRef(null),[p,g]=react.useState(true),l=react.useRef(0),c=react.useRef(null),i=react.useCallback(t=>{let e=o.current;if(!e)return;let f=t??(h?"smooth":"instant");c.current=f,e.scrollTo({top:e.scrollHeight,behavior:f});},[h]),u=react.useCallback(t=>Math.abs(t.scrollHeight-t.scrollTop-t.clientHeight)<1||t.scrollHeight<=t.clientHeight,[]),m=react.useCallback(()=>{let t=o.current;if(!t)return;let e=u(t);!e&&l.current<t.scrollTop||(e&&(c.current=null),(e||c.current===null)&&g(e)),l.current=t.scrollTop;},[u]),r=react.useCallback(()=>{let t=c.current;if(t)i(t);else if(s){let e=o.current;e&&u(e)&&i("instant");}m();},[s,i,u,m]);return react.useEffect(()=>{let t=o.current;if(!t||!s)return;let e=new ResizeObserver(()=>{r();});return e.observe(t),()=>e.disconnect()},[s,r]),react.useEffect(()=>{let t=o.current;if(!t||!s)return;let e=new MutationObserver(f=>{f.some(v=>v.type!=="attributes"||v.attributeName!=="style")&&r();});return e.observe(t,{childList:true,subtree:true,attributes:true,characterData:true}),()=>e.disconnect()},[s,r]),react.useEffect(()=>{let t=o.current;if(t)return t.addEventListener("scroll",m,{passive:true}),()=>t.removeEventListener("scroll",m)},[m]),react.useEffect(()=>{s&&T&&(c.current="instant",requestAnimationFrame(()=>{i("instant");}));},[]),{containerRef:o,scrollToBottom:i,isAtBottom:p}}function z({onSubmit:s,disabled:h=false,maxFileSize:T=10*1024*1024,allowedFileTypes:o}){let[p,g]=react.useState(""),[l,c]=react.useState([]),[i,u]=react.useState(false),[m,r]=react.useState(null),t=react.useRef(null),e=react.useCallback(n=>{g(n),r(null);},[]),f=react.useCallback(n=>{let b=Array.from(n),y=[];for(let a of b){if(a.size>T){r(`File "${a.name}" exceeds maximum size`);continue}if(o&&!o.includes(a.type)){r(`File type "${a.type}" is not allowed`);continue}y.push(a);}c(a=>[...a,...y]);},[T,o]),E=react.useCallback(n=>{c(b=>b.filter((y,a)=>a!==n));},[]),v=react.useCallback(async()=>{let n=p.trim();if(!(!n&&l.length===0||h||i)){u(true),r(null);try{await s(n,l.length>0?l:void 0),g(""),c([]),t.current?.focus();}catch(b){r(b instanceof Error?b.message:"Failed to send message");}finally{u(false);}}},[p,l,h,i,s]),M=react.useCallback(n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),v());},[v]),x=react.useCallback(()=>{g(""),c([]),r(null);},[]),C=(p.trim()||l.length>0)&&!h&&!i;return {content:p,attachments:l,isSubmitting:i,error:m,canSubmit:C,inputRef:t,handleContentChange:e,handleAddAttachment:f,handleRemoveAttachment:E,handleSubmit:v,handleKeyDown:M,clear:x}}exports.a=L;exports.b=z;//# sourceMappingURL=chunk-TOYU46SZ.cjs.map
|
|
2
|
-
//# sourceMappingURL=chunk-TOYU46SZ.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-auto-scroll.ts","../src/hooks/use-message-composer.ts"],"names":["useAutoScroll","enabled","smooth","scrollToBottomOnMount","containerRef","useRef","isAtBottom","setIsAtBottom","useState","lastScrollTopRef","scrollingToBottomBehaviorRef","scrollToBottom","useCallback","behavior","container","b","computeIsAtBottom","el","handleScroll","newIsAtBottom","handleContentResize","scrollBehavior","useEffect","resizeObserver","mutationObserver","mutations","m","useMessageComposer","onSubmit","disabled","maxFileSize","allowedFileTypes","content","setContent","attachments","setAttachments","isSubmitting","setIsSubmitting","error","setError","inputRef","handleContentChange","value","handleAddAttachment","files","fileArray","validFiles","file","prev","handleRemoveAttachment","index","_","i","handleSubmit","trimmedContent","err","handleKeyDown","e","clear","canSubmit"],"mappings":"wCA+BO,SAASA,EAAqC,CACnD,OAAA,CAAAC,CAAAA,CAAU,IAAA,CACV,OAAAC,CAAAA,CAAS,IAAA,CACT,qBAAA,CAAAC,CAAAA,CAAwB,IAC1B,CAAA,CAA0B,EAAC,CAA2B,CACpD,IAAMC,CAAAA,CAAeC,YAAAA,CAAU,IAAI,CAAA,CAC7B,CAACC,CAAAA,CAAYC,CAAa,CAAA,CAAIC,cAAAA,CAAS,IAAI,CAAA,CAC3CC,CAAAA,CAAmBJ,YAAAA,CAAO,CAAC,EAO3BK,CAAAA,CAA+BL,YAAAA,CAA8B,IAAI,CAAA,CAEjEM,EAAiBC,iBAAAA,CACpBC,CAAAA,EAA8B,CAC7B,IAAMC,EAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAI,CAACU,EAAW,OAEhB,IAAMC,CAAAA,CAAIF,CAAAA,GAAaX,EAAS,QAAA,CAAW,SAAA,CAAA,CAC3CQ,CAAAA,CAA6B,OAAA,CAAUK,EACvCD,CAAAA,CAAU,QAAA,CAAS,CAAE,GAAA,CAAKA,EAAU,YAAA,CAAc,QAAA,CAAUC,CAAE,CAAC,EACjE,CAAA,CACA,CAACb,CAAM,CACT,EAGMc,CAAAA,CAAoBJ,iBAAAA,CAAaK,CAAAA,EAEnC,IAAA,CAAK,IAAIA,CAAAA,CAAG,YAAA,CAAeA,CAAAA,CAAG,SAAA,CAAYA,EAAG,YAAY,CAAA,CAAI,CAAA,EAC7DA,CAAAA,CAAG,cAAgBA,CAAAA,CAAG,YAAA,CAEvB,EAAE,EAGCC,CAAAA,CAAeN,iBAAAA,CAAY,IAAM,CACrC,IAAME,CAAAA,CAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAI,CAACU,CAAAA,CAAW,OAEhB,IAAMK,CAAAA,CAAgBH,EAAkBF,CAAS,CAAA,CAI7C,CAACK,CAAAA,EAAiBV,EAAiB,OAAA,CAAUK,CAAAA,CAAU,SAAA,GAGrDK,CAAAA,GACFT,EAA6B,OAAA,CAAU,IAAA,CAAA,CAAA,CAMvCS,CAAAA,EAAiBT,CAAAA,CAA6B,UAAY,IAAA,GAG1DH,CAAAA,CAAcY,CAAa,CAAA,CAAA,CAI/BV,EAAiB,OAAA,CAAUK,CAAAA,CAAU,UACvC,CAAA,CAAG,CAACE,CAAiB,CAAC,CAAA,CAGhBI,CAAAA,CAAsBR,kBAAY,IAAM,CAC5C,IAAMS,CAAAA,CAAiBX,EAA6B,OAAA,CACpD,GAAIW,EAEFV,CAAAA,CAAeU,CAAc,UACpBpB,CAAAA,CAAS,CAElB,IAAMa,CAAAA,CAAYV,EAAa,OAAA,CAC3BU,CAAAA,EAAaE,CAAAA,CAAkBF,CAAS,GAC1CH,CAAAA,CAAe,SAAS,EAE5B,CAEAO,IACF,CAAA,CAAG,CAACjB,CAAAA,CAASU,EAAgBK,CAAAA,CAAmBE,CAAY,CAAC,CAAA,CAG7D,OAAAI,eAAAA,CAAU,IAAM,CACd,IAAMR,EAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAI,CAACU,GAAa,CAACb,CAAAA,CAAS,OAE5B,IAAMsB,EAAiB,IAAI,cAAA,CAAe,IAAM,CAC9CH,IACF,CAAC,CAAA,CAED,OAAAG,EAAe,OAAA,CAAQT,CAAS,CAAA,CACzB,IAAMS,EAAe,UAAA,EAC9B,CAAA,CAAG,CAACtB,EAASmB,CAAmB,CAAC,CAAA,CAGjCE,eAAAA,CAAU,IAAM,CACd,IAAMR,CAAAA,CAAYV,CAAAA,CAAa,QAC/B,GAAI,CAACU,CAAAA,EAAa,CAACb,EAAS,OAE5B,IAAMuB,EAAmB,IAAI,gBAAA,CAAkBC,GAAc,CAG/BA,CAAAA,CAAU,IAAA,CACnCC,CAAAA,EAAMA,EAAE,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAE,aAAA,GAAkB,OACxD,CAAA,EAEEN,CAAAA,GAEJ,CAAC,EAED,OAAAI,CAAAA,CAAiB,OAAA,CAAQV,CAAAA,CAAW,CAClC,SAAA,CAAW,IAAA,CACX,OAAA,CAAS,IAAA,CACT,WAAY,IAAA,CACZ,aAAA,CAAe,IACjB,CAAC,EAEM,IAAMU,CAAAA,CAAiB,UAAA,EAChC,EAAG,CAACvB,CAAAA,CAASmB,CAAmB,CAAC,EAGjCE,eAAAA,CAAU,IAAM,CACd,IAAMR,EAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAKU,CAAAA,CAEL,OAAAA,CAAAA,CAAU,gBAAA,CAAiB,QAAA,CAAUI,CAAAA,CAAc,CAAE,OAAA,CAAS,IAAK,CAAC,CAAA,CAC7D,IAAMJ,CAAAA,CAAU,mBAAA,CAAoB,QAAA,CAAUI,CAAY,CACnE,CAAA,CAAG,CAACA,CAAY,CAAC,EAGjBI,eAAAA,CAAU,IAAM,CACVrB,CAAAA,EAAWE,IAEbO,CAAAA,CAA6B,OAAA,CAAU,UACvC,qBAAA,CAAsB,IAAM,CAC1BC,CAAAA,CAAe,SAAS,EAC1B,CAAC,GAIL,CAAA,CAAG,EAAE,CAAA,CAEE,CACL,YAAA,CAAAP,CAAAA,CACA,cAAA,CAAAO,CAAAA,CACA,WAAAL,CACF,CACF,CCnKO,SAASqB,CAAAA,CAAmB,CACjC,SAAAC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CAAW,KAAA,CACX,YAAAC,CAAAA,CAAc,EAAA,CAAK,IAAA,CAAO,IAAA,CAC1B,iBAAAC,CACF,CAAA,CAA8B,CAC5B,GAAM,CAACC,CAAAA,CAASC,CAAU,CAAA,CAAIzB,cAAAA,CAAS,EAAE,CAAA,CACnC,CAAC0B,CAAAA,CAAaC,CAAc,EAAI3B,cAAAA,CAAiB,EAAE,CAAA,CACnD,CAAC4B,CAAAA,CAAcC,CAAe,CAAA,CAAI7B,cAAAA,CAAS,KAAK,CAAA,CAChD,CAAC8B,CAAAA,CAAOC,CAAQ,EAAI/B,cAAAA,CAAwB,IAAI,CAAA,CAEhDgC,CAAAA,CAAWnC,aAA4B,IAAI,CAAA,CAE3CoC,CAAAA,CAAsB7B,iBAAAA,CAAa8B,GAAkB,CACzDT,CAAAA,CAAWS,CAAK,CAAA,CAChBH,EAAS,IAAI,EACf,CAAA,CAAG,EAAE,CAAA,CAECI,CAAAA,CAAsB/B,iBAAAA,CACzBgC,CAAAA,EAA6B,CAC5B,IAAMC,CAAAA,CAAY,KAAA,CAAM,IAAA,CAAKD,CAAK,CAAA,CAC5BE,CAAAA,CAAqB,EAAC,CAE5B,QAAWC,CAAAA,IAAQF,CAAAA,CAAW,CAE5B,GAAIE,EAAK,IAAA,CAAOjB,CAAAA,CAAa,CAC3BS,CAAAA,CAAS,SAASQ,CAAAA,CAAK,IAAI,CAAA,sBAAA,CAAwB,CAAA,CACnD,QACF,CAGA,GAAIhB,CAAAA,EAAoB,CAACA,EAAiB,QAAA,CAASgB,CAAAA,CAAK,IAAI,CAAA,CAAG,CAC7DR,CAAAA,CAAS,CAAA,WAAA,EAAcQ,CAAAA,CAAK,IAAI,kBAAkB,CAAA,CAClD,QACF,CAEAD,CAAAA,CAAW,KAAKC,CAAI,EACtB,CAEAZ,CAAAA,CAAgBa,GAAS,CAAC,GAAGA,CAAAA,CAAM,GAAGF,CAAU,CAAC,EACnD,CAAA,CACA,CAAChB,EAAaC,CAAgB,CAChC,EAEMkB,CAAAA,CAAyBrC,iBAAAA,CAAasC,GAAkB,CAC5Df,CAAAA,CAAgBa,CAAAA,EAASA,CAAAA,CAAK,OAAO,CAACG,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,GAAMF,CAAK,CAAC,EAC7D,CAAA,CAAG,EAAE,CAAA,CAECG,CAAAA,CAAezC,iBAAAA,CAAY,SAAY,CAC3C,IAAM0C,CAAAA,CAAiBtB,CAAAA,CAAQ,IAAA,GAC/B,GAAK,EAAA,CAACsB,CAAAA,EAAkBpB,CAAAA,CAAY,SAAW,CAAA,EAAML,CAAAA,EAAYO,CAAAA,CAAAA,CAIjE,CAAAC,EAAgB,IAAI,CAAA,CACpBE,CAAAA,CAAS,IAAI,EAEb,GAAI,CACF,MAAMX,CAAAA,CAAS0B,EAAgBpB,CAAAA,CAAY,MAAA,CAAS,CAAA,CAAIA,CAAAA,CAAc,MAAS,CAAA,CAC/ED,CAAAA,CAAW,EAAE,CAAA,CACbE,EAAe,EAAE,CAAA,CACjBK,CAAAA,CAAS,SAAS,KAAA,GACpB,CAAA,MAASe,CAAAA,CAAK,CACZhB,CAAAA,CAASgB,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,wBAAwB,EACxE,CAAA,OAAE,CACAlB,EAAgB,KAAK,EACvB,EACF,CAAA,CAAG,CAACL,EAASE,CAAAA,CAAaL,CAAAA,CAAUO,CAAAA,CAAcR,CAAQ,CAAC,CAAA,CAErD4B,CAAAA,CAAgB5C,iBAAAA,CACnB6C,CAAAA,EAA0C,CAErCA,CAAAA,CAAE,GAAA,GAAQ,OAAA,EAAW,CAACA,EAAE,QAAA,GAC1BA,CAAAA,CAAE,cAAA,EAAe,CACjBJ,GAAa,EAEjB,CAAA,CACA,CAACA,CAAY,CACf,CAAA,CAEMK,CAAAA,CAAQ9C,iBAAAA,CAAY,IAAM,CAC9BqB,CAAAA,CAAW,EAAE,CAAA,CACbE,CAAAA,CAAe,EAAE,CAAA,CACjBI,CAAAA,CAAS,IAAI,EACf,CAAA,CAAG,EAAE,CAAA,CAECoB,GAAa3B,CAAAA,CAAQ,IAAA,EAAK,EAAKE,CAAAA,CAAY,OAAS,CAAA,GAAM,CAACL,CAAAA,EAAY,CAACO,EAE9E,OAAO,CACL,OAAA,CAAAJ,CAAAA,CACA,YAAAE,CAAAA,CACA,YAAA,CAAAE,CAAAA,CACA,KAAA,CAAAE,EACA,SAAA,CAAAqB,CAAAA,CACA,QAAA,CAAAnB,CAAAA,CACA,oBAAAC,CAAAA,CACA,mBAAA,CAAAE,CAAAA,CACA,sBAAA,CAAAM,EACA,YAAA,CAAAI,CAAAA,CACA,cAAAG,CAAAA,CACA,KAAA,CAAAE,CACF,CACF","file":"chunk-TOYU46SZ.cjs","sourcesContent":["import { useEffect, useRef, useCallback, useState } from \"react\";\n\nexport interface UseAutoScrollOptions {\n /** Whether auto-scroll is enabled */\n enabled?: boolean;\n /** Smooth scroll behavior */\n smooth?: boolean;\n /** Scroll to bottom when component mounts */\n scrollToBottomOnMount?: boolean;\n}\n\nexport interface UseAutoScrollReturn<T extends HTMLElement> {\n /** Ref to attach to the scrollable container */\n containerRef: React.RefObject<T | null>;\n /** Scroll to bottom programmatically (always forces scroll) */\n scrollToBottom: (behavior?: ScrollBehavior) => void;\n /** Whether the viewport is currently at the bottom */\n isAtBottom: boolean;\n}\n\n/**\n * Hook to automatically scroll to the bottom of a container\n * when new content is added, unless the user has scrolled up.\n *\n * Combines ResizeObserver + MutationObserver to catch all height changes\n * (image loads, panel expansion, streaming text, new messages).\n *\n * Uses a 1px tolerance for isAtBottom (matches assistant-ui) and\n * persists scroll behavior across content resize to prevent\n * the \"content outraces scroll\" bug.\n */\nexport function useAutoScroll<T extends HTMLElement>({\n enabled = true,\n smooth = true,\n scrollToBottomOnMount = true,\n}: UseAutoScrollOptions = {}): UseAutoScrollReturn<T> {\n const containerRef = useRef<T>(null);\n const [isAtBottom, setIsAtBottom] = useState(true);\n const lastScrollTopRef = useRef(0);\n\n // When scrollToBottom() is called, store the behavior.\n // On subsequent resize/mutation callbacks, re-scroll with the same behavior\n // until the bottom is actually reached. This prevents the \"content outraces\n // scroll\" bug where new content pushes the bottom away faster than smooth\n // scrolling can reach it.\n const scrollingToBottomBehaviorRef = useRef<ScrollBehavior | null>(null);\n\n const scrollToBottom = useCallback(\n (behavior?: ScrollBehavior) => {\n const container = containerRef.current;\n if (!container) return;\n\n const b = behavior ?? (smooth ? \"smooth\" : \"instant\");\n scrollingToBottomBehaviorRef.current = b;\n container.scrollTo({ top: container.scrollHeight, behavior: b });\n },\n [smooth],\n );\n\n // Determine if we're at the bottom (1px tolerance, or content fits without scroll)\n const computeIsAtBottom = useCallback((el: HTMLElement): boolean => {\n return (\n Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) < 1 ||\n el.scrollHeight <= el.clientHeight\n );\n }, []);\n\n // Scroll event handler — updates isAtBottom state\n const handleScroll = useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const newIsAtBottom = computeIsAtBottom(container);\n\n // If user is scrolling UP while we're in the middle of a scrollToBottom,\n // don't flip isAtBottom to false (ignore scroll-down momentum).\n if (!newIsAtBottom && lastScrollTopRef.current < container.scrollTop) {\n // Scroll is moving down — likely from our scrollToBottom call, ignore\n } else {\n if (newIsAtBottom) {\n scrollingToBottomBehaviorRef.current = null;\n }\n\n // Only update state when behavior ref is cleared (i.e. not mid-scroll)\n // or when we actually reached the bottom\n const shouldUpdate =\n newIsAtBottom || scrollingToBottomBehaviorRef.current === null;\n\n if (shouldUpdate) {\n setIsAtBottom(newIsAtBottom);\n }\n }\n\n lastScrollTopRef.current = container.scrollTop;\n }, [computeIsAtBottom]);\n\n // Content resize handler — called by both ResizeObserver and MutationObserver\n const handleContentResize = useCallback(() => {\n const scrollBehavior = scrollingToBottomBehaviorRef.current;\n if (scrollBehavior) {\n // We're in the middle of a scrollToBottom — keep chasing the bottom\n scrollToBottom(scrollBehavior);\n } else if (enabled) {\n // Auto-scroll only if already at bottom\n const container = containerRef.current;\n if (container && computeIsAtBottom(container)) {\n scrollToBottom(\"instant\");\n }\n }\n\n handleScroll();\n }, [enabled, scrollToBottom, computeIsAtBottom, handleScroll]);\n\n // ResizeObserver — catches height changes from image loads, layout shifts, etc.\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !enabled) return;\n\n const resizeObserver = new ResizeObserver(() => {\n handleContentResize();\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, [enabled, handleContentResize]);\n\n // MutationObserver — catches new messages, streaming text, DOM changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !enabled) return;\n\n const mutationObserver = new MutationObserver((mutations) => {\n // Filter out style-only attribute mutations to prevent feedback loops\n // (e.g. components that write styles in response to viewport changes)\n const hasRelevantMutation = mutations.some(\n (m) => m.type !== \"attributes\" || m.attributeName !== \"style\",\n );\n if (hasRelevantMutation) {\n handleContentResize();\n }\n });\n\n mutationObserver.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n return () => mutationObserver.disconnect();\n }, [enabled, handleContentResize]);\n\n // Scroll listener\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener(\"scroll\", handleScroll, { passive: true });\n return () => container.removeEventListener(\"scroll\", handleScroll);\n }, [handleScroll]);\n\n // Scroll to bottom on mount\n useEffect(() => {\n if (enabled && scrollToBottomOnMount) {\n // Use instant on mount — no need for smooth animation on initial load\n scrollingToBottomBehaviorRef.current = \"instant\";\n requestAnimationFrame(() => {\n scrollToBottom(\"instant\");\n });\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return {\n containerRef,\n scrollToBottom,\n isAtBottom,\n };\n}\n","import { useState, useCallback, useRef, type KeyboardEvent } from \"react\";\n\ninterface UseMessageComposerOptions {\n /** Callback when message is submitted */\n onSubmit: (content: string, attachments?: File[]) => Promise<void>;\n /** Whether submission is disabled */\n disabled?: boolean;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed file types (MIME types) */\n allowedFileTypes?: string[];\n}\n\n/**\n * Hook to manage message composer state and behavior.\n */\nexport function useMessageComposer({\n onSubmit,\n disabled = false,\n maxFileSize = 10 * 1024 * 1024, // 10MB\n allowedFileTypes,\n}: UseMessageComposerOptions) {\n const [content, setContent] = useState(\"\");\n const [attachments, setAttachments] = useState<File[]>([]);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n const handleContentChange = useCallback((value: string) => {\n setContent(value);\n setError(null);\n }, []);\n\n const handleAddAttachment = useCallback(\n (files: FileList | File[]) => {\n const fileArray = Array.from(files);\n const validFiles: File[] = [];\n\n for (const file of fileArray) {\n // Check file size\n if (file.size > maxFileSize) {\n setError(`File \"${file.name}\" exceeds maximum size`);\n continue;\n }\n\n // Check file type\n if (allowedFileTypes && !allowedFileTypes.includes(file.type)) {\n setError(`File type \"${file.type}\" is not allowed`);\n continue;\n }\n\n validFiles.push(file);\n }\n\n setAttachments((prev) => [...prev, ...validFiles]);\n },\n [maxFileSize, allowedFileTypes]\n );\n\n const handleRemoveAttachment = useCallback((index: number) => {\n setAttachments((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n const handleSubmit = useCallback(async () => {\n const trimmedContent = content.trim();\n if ((!trimmedContent && attachments.length === 0) || disabled || isSubmitting) {\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n await onSubmit(trimmedContent, attachments.length > 0 ? attachments : undefined);\n setContent(\"\");\n setAttachments([]);\n inputRef.current?.focus();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to send message\");\n } finally {\n setIsSubmitting(false);\n }\n }, [content, attachments, disabled, isSubmitting, onSubmit]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n // Submit on Enter without Shift\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const clear = useCallback(() => {\n setContent(\"\");\n setAttachments([]);\n setError(null);\n }, []);\n\n const canSubmit = (content.trim() || attachments.length > 0) && !disabled && !isSubmitting;\n\n return {\n content,\n attachments,\n isSubmitting,\n error,\n canSubmit,\n inputRef,\n handleContentChange,\n handleAddAttachment,\n handleRemoveAttachment,\n handleSubmit,\n handleKeyDown,\n clear,\n };\n}\n"]}
|
package/dist/chunk-ZKMXEECD.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use strict';var react=require('react');function b(r={}){let[c,i]=react.useState({isStreaming:false,streamingMessageId:null,streamedContent:""}),n=react.useRef(null),m=react.useCallback(e=>{i({isStreaming:true,streamingMessageId:e,streamedContent:""}),n.current=new AbortController;},[]),p=react.useCallback(e=>{e.type==="content"&&e.content&&i(u=>({...u,streamedContent:u.streamedContent+e.content})),r.onChunk?.(e);},[r]),d=react.useCallback(()=>{n.current?.abort();let e=c.streamedContent;i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onComplete?.(e);},[c.streamedContent,r]),S=react.useCallback(e=>{n.current?.abort(),i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onError?.(e);},[r]);return {...c,startStreaming:m,appendContent:p,stopStreaming:d,handleError:S,abortSignal:n.current?.signal}}function x({maxCount:r=5,maxFileSize:c=10*1024*1024,allowedTypes:i}={}){let[n,m]=react.useState([]),p=react.useCallback(t=>{if(n.length>=r)return {success:false,error:`Maximum ${r} attachments allowed`};if(t.size>c)return {success:false,error:`File size exceeds ${Math.round(c/1024/1024)}MB limit`};if(i&&!i.includes(t.type))return {success:false,error:`File type ${t.type} not allowed`};let o=`${Date.now()}-${Math.random().toString(36).slice(2)}`;return m(a=>[...a,{file:t,id:o,progress:0,status:"pending"}]),{success:true}},[n.length,r,c,i]),d=react.useCallback(t=>{m(o=>o.filter(a=>a.id!==t));},[]),S=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,progress:o,status:o<100?"uploading":"complete"}:s));},[]),e=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,status:"error",error:o}:s));},[]),u=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,url:o,status:"complete",progress:100}:s));},[]),f=react.useCallback(()=>{m([]);},[]),C=react.useCallback(()=>n.map(t=>t.file),[n]);return {attachments:n,addAttachment:p,removeAttachment:d,updateProgress:S,setError:e,setUrl:u,clear:f,getFiles:C,canAddMore:n.length<r}}exports.a=b;exports.b=x;//# sourceMappingURL=chunk-ZKMXEECD.cjs.map
|
|
2
|
-
//# sourceMappingURL=chunk-ZKMXEECD.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-ZKMXEECD.cjs","sourcesContent":["import { useState, useCallback, useRef } from \"react\";\nimport type { StreamingState, StreamChunk, StreamingOptions } from \"../types\";\n\n/**\n * Hook to manage streaming message state.\n */\nexport function useStreaming(options: StreamingOptions = {}) {\n const [state, setState] = useState<StreamingState>({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const startStreaming = useCallback((messageId: string) => {\n setState({\n isStreaming: true,\n streamingMessageId: messageId,\n streamedContent: \"\",\n });\n abortControllerRef.current = new AbortController();\n }, []);\n\n const appendContent = useCallback(\n (chunk: StreamChunk) => {\n if (chunk.type === \"content\" && chunk.content) {\n setState((prev) => ({\n ...prev,\n streamedContent: prev.streamedContent + chunk.content,\n }));\n }\n options.onChunk?.(chunk);\n },\n [options]\n );\n\n const stopStreaming = useCallback(() => {\n abortControllerRef.current?.abort();\n const finalContent = state.streamedContent;\n\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n options.onComplete?.(finalContent);\n }, [state.streamedContent, options]);\n\n const handleError = useCallback(\n (error: Error) => {\n abortControllerRef.current?.abort();\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n options.onError?.(error);\n },\n [options]\n );\n\n return {\n ...state,\n startStreaming,\n appendContent,\n stopStreaming,\n handleError,\n abortSignal: abortControllerRef.current?.signal,\n };\n}\n","import { useState, useCallback } from \"react\";\n\ninterface AttachmentState {\n file: File;\n id: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"complete\" | \"error\";\n error?: string;\n url?: string;\n}\n\ninterface UseAttachmentsOptions {\n /** Maximum number of attachments */\n maxCount?: number;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed MIME types */\n allowedTypes?: string[];\n}\n\n/**\n * Hook to manage file attachments with upload progress.\n */\nexport function useAttachments({\n maxCount = 5,\n maxFileSize = 10 * 1024 * 1024,\n allowedTypes,\n}: UseAttachmentsOptions = {}) {\n const [attachments, setAttachments] = useState<AttachmentState[]>([]);\n\n const addAttachment = useCallback(\n (file: File): { success: boolean; error?: string } => {\n // Check count\n if (attachments.length >= maxCount) {\n return { success: false, error: `Maximum ${maxCount} attachments allowed` };\n }\n\n // Check size\n if (file.size > maxFileSize) {\n return {\n success: false,\n error: `File size exceeds ${Math.round(maxFileSize / 1024 / 1024)}MB limit`,\n };\n }\n\n // Check type\n if (allowedTypes && !allowedTypes.includes(file.type)) {\n return { success: false, error: `File type ${file.type} not allowed` };\n }\n\n const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n setAttachments((prev) => [\n ...prev,\n {\n file,\n id,\n progress: 0,\n status: \"pending\",\n },\n ]);\n\n return { success: true };\n },\n [attachments.length, maxCount, maxFileSize, allowedTypes]\n );\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const updateProgress = useCallback((id: string, progress: number) => {\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === id\n ? { ...a, progress, status: progress < 100 ? \"uploading\" : \"complete\" }\n : a\n )\n );\n }, []);\n\n const setError = useCallback((id: string, error: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, status: \"error\", error } : a))\n );\n }, []);\n\n const setUrl = useCallback((id: string, url: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, url, status: \"complete\", progress: 100 } : a))\n );\n }, []);\n\n const clear = useCallback(() => {\n setAttachments([]);\n }, []);\n\n const getFiles = useCallback(() => {\n return attachments.map((a) => a.file);\n }, [attachments]);\n\n return {\n attachments,\n addAttachment,\n removeAttachment,\n updateProgress,\n setError,\n setUrl,\n clear,\n getFiles,\n canAddMore: attachments.length < maxCount,\n };\n}\n"]}
|
package/dist/client/index.cjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
'use strict';var chunkKSMAVBLY_cjs=require('../chunk-KSMAVBLY.cjs'),react=require('react');function E(t){return t.baseUrl?t.baseUrl.replace(/\/api\/?$/,""):t.bundleUrl?.includes("localhost")||t.bundleUrl?.includes("127.0.0.1")||false?"http://localhost:8003":"https://api.miiflow.ai"}function U(){let t="miiflow-user-id",n=null;try{n=localStorage.getItem(t);}catch{}if(!n){n=`muid_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;try{localStorage.setItem(t,n);}catch{}}return n}async function ue(t){let n=E(t),u=await fetch(`${n}/api/embed/init`,{method:"POST",headers:{"Content-Type":"application/json","X-Embed-Public-Key":t.publicKey,"x-mii-user-id":U()},body:JSON.stringify({assistant_id:t.assistantId,user_data:{user_id:t.userId,name:t.userName,email:t.userEmail}})});if(!u.ok){let p=await u.text();throw new Error(`Init failed: ${u.status} - ${p}`)}let c=await u.json();if(!c.success)throw new Error(c.error||"Failed to initialize session");return {token:c.token,config:c.config,session_id:c.session_id}}async function ce(t,n){let u=E(t),c=await fetch(`${u}/api/embed/graphql`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`,"x-mii-user-id":U()},body:JSON.stringify({operationName:"CreateThread",variables:{input:{assistantId:n.config.assistant_id,name:"New Thread",isPreview:false}},query:`mutation CreateThread($input: CreateThreadInput!) {
|
|
2
|
-
createThread(input: $input) {
|
|
3
|
-
thread { id status name isPreview }
|
|
4
|
-
}
|
|
5
|
-
}`})});if(!c.ok)throw new Error(`Failed to create thread: ${c.status}`);let p=await c.json(),_=p.data?.createThread?.thread?.id;if(!_)throw new Error("No thread ID returned");return {threadId:_,token:p.token}}async function ke(t,n,u){let c=E(t);await fetch(`${c}/api/embed/update`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify({user_data:u})});}async function de(t,n,u){let p=`${E(t)}/api/embed/upload-attachment`,_=new FormData;_.append("file",u);let f=await fetch(p,{method:"POST",headers:{Authorization:`Bearer ${n.token}`,"x-mii-user-id":U()},body:_});if(!f.ok){let P=await f.text();throw new Error(`Upload failed: ${f.status} - ${P}`)}let s=(await f.json()).attachment?.id;if(!s)throw new Error("No attachment ID returned");return s}async function pe(t,n,u){let c=E(t),p=await fetch(`${c}/api/embed/system-event`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:n.config.thread_id,system_event:{action:u.action,description:u.description,followUpInstruction:u.followUpInstruction,metadata:u.metadata||{}}})});if(!p.ok){let f=await p.text();throw new Error(`Failed to send system event: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(_.error||"Failed to send system event")}async function G(t,n,u){let c=E(t),p=await fetch(`${c}/api/embed/tool-result`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(u)});if(!p.ok){let f=await p.text();throw new Error(`Failed to send tool result: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(`Failed to send tool result: ${_.error}`)}async function Q(t,n,u){let c=E(t);if(u.length===1){let p=await fetch(`${c}/api/embed/register-tool`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(u[0])});if(!p.ok){let f=await p.text();throw new Error(`Failed to register tool: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(`Failed to register tool: ${_.error||"Unknown error"}`)}else if(u.length>1){let p=await fetch(`${c}/api/embed/register-tools`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(u)});if(!p.ok){let f=await p.text();throw new Error(`Failed to register tools: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(`Failed to register tools: ${_.error||"Unknown error"}`)}}var ge=new Set(["string","number","integer","boolean","array","object","null"]),Se=/^[a-zA-Z_][a-zA-Z0-9_]*$/,y=class extends Error{constructor(n){super(n),this.name="ToolValidationError";}};function ie(t){if(!t.name)throw new y("Tool name is required");if(!t.description)throw new y("Tool description is required");if(!t.parameters)throw new y("Tool parameters schema is required");if(typeof t.handler!="function")throw new y("Tool handler must be a function");Ce(t.name),Te(t.description),Ie(t.parameters);}function Ce(t){if(typeof t!="string")throw new y("Tool name must be a string");if(t.length===0)throw new y("Tool name cannot be empty");if(t.length>64)throw new y("Tool name too long (max 64 characters)");if(!Se.test(t))throw new y("Tool name must start with letter/underscore and contain only alphanumeric characters and underscores")}function Te(t){if(typeof t!="string")throw new y("Tool description must be a string");if(t.trim().length===0)throw new y("Tool description cannot be empty");if(t.length>500)throw new y("Tool description too long (max 500 characters)")}function Ie(t){if(typeof t!="object"||t===null||Array.isArray(t))throw new y("Parameters must be a JSON Schema object");if(t.type!=="object")throw new y("Parameters schema must be of type 'object' (function parameters)");if(t.properties&&typeof t.properties=="object")for(let[n,u]of Object.entries(t.properties))oe(n,u);if(t.required!==void 0){if(!Array.isArray(t.required))throw new y("'required' must be an array");for(let n of t.required)if(typeof n!="string")throw new y("'required' array must contain only strings")}if(t.additionalProperties!==void 0&&typeof t.additionalProperties!="boolean"&&(typeof t.additionalProperties!="object"||t.additionalProperties===null))throw new y("'additionalProperties' must be boolean or object")}function oe(t,n){if(typeof n!="object"||n===null||Array.isArray(n))throw new y(`Property '${t}' schema must be an object`);if(n.type!==void 0){let u=Array.isArray(n.type)?n.type:[n.type];for(let c of u)if(!ge.has(c))throw new y(`Invalid type '${c}' for property '${t}'. Valid types: ${Array.from(ge).join(", ")}`)}if(n.enum!==void 0&&!Array.isArray(n.enum))throw new y(`Property '${t}' enum must be an array`);if(n.properties&&typeof n.properties=="object")for(let[u,c]of Object.entries(n.properties))oe(`${t}.${u}`,c);n.items&&(Array.isArray(n.items)?n.items.forEach((u,c)=>{oe(`${t}[${c}]`,u);}):oe(`${t}[]`,n.items));}function re(t){return {name:t.name,description:t.description,parameters:t.parameters}}var De=21e3,xe=1e3,ve=3e4;function Ae(t,n){if(t.webSocketUrl){let f=new URL(t.webSocketUrl);return f.pathname=`/ws/assistant/thread/${n.config.thread_id}/`,f.searchParams.set("role","user"),f.searchParams.set("user_id",U()),f.searchParams.set("embed_token",n.token),f.toString()}let p=E(t).replace(/\/api$/,"").replace(/^https:/,"wss:").replace(/^http:/,"ws:"),_=U();return `${p}/ws/assistant/thread/${n.config.thread_id}/?role=user&user_id=${encodeURIComponent(_)}&embed_token=${encodeURIComponent(n.token)}`}function Me(t){let n=t?.config.branding;return n?{customName:n.custom_name,messageFontSize:n.message_font_size,welcomeMessage:n.welcome_message,chatboxPlaceholder:n.chatbox_placeholder,backgroundBubbleColor:n.background_bubble_color,headerBackgroundColor:n.header_background_color,showHeader:n.show_header,rotatingPlaceholders:n.rotating_placeholders,presetQuestions:n.preset_questions,chatbotLogo:n.chatbot_logo,assistantAvatar:n.assistant_avatar}:null}async function Ee(t,n,u,c){let p=new TextDecoder,_=Date.now(),f="",b=null,s=[],P,z,ee=false,I="answer",g="",S,F,A,x,B,W,N,q,J,O,H,L,X,V,te=false,Z="",ne=n.config.branding,o=()=>{(g||I==="tool")&&(s.push({type:I,content:g,toolName:S,toolDescription:F,success:A,status:x,subtaskId:B,planData:W,subtaskData:N,isSynthesis:q,isReplan:J,toolArgs:O,replanAttempt:H,maxReplans:L,failureReason:X,progress:V}),g="",S=void 0,F=void 0,A=void 0,x=void 0,B=void 0,W=void 0,N=void 0,q=void 0,J=void 0,O=void 0,H=void 0,L=void 0,X=void 0,V=void 0);},d=()=>{let m=s.map(C=>C);return (g||I==="tool")&&m.push({type:I,content:g,toolName:S,toolDescription:F,success:A,status:x,subtaskId:B,planData:W,subtaskData:N,isSynthesis:q,isReplan:J,toolArgs:O,replanAttempt:H,maxReplans:L,failureReason:X,progress:V}),m},i=()=>{let m=d();if(b)c.onMessageUpdate({id:b,textContent:f,reasoning:m,suggestedActions:P});else {b=`assistant-${Date.now()}`;let C={id:b,textContent:f,participant:{id:"assistant",name:ne?.custom_name||n.config.assistant_name,role:"assistant",avatarUrl:ne?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true,reasoning:m,suggestedActions:P};c.onMessageCreate(C);}};for(;;){let{done:m,value:C}=await t.read();if(m)break;let h=p.decode(C,{stream:true}),j=(Z+h).split(`
|
|
6
|
-
`);h.endsWith(`
|
|
7
|
-
`)?Z="":Z=j.pop()||"";for(let T of j){if(!T.startsWith("data: "))continue;let M=T.slice(6);if(M==="[DONE]")break;try{let e=JSON.parse(M);if(e.type==="assistant_chunk"){if(e.is_tool_planned){(g||I!=="answer")&&(o(),I="answer"),s.push({type:"tool",content:"",toolName:e.tool_name,toolDescription:e.tool_description,status:"planned",subtaskId:e.subtask_id}),i();continue}if(e.is_tool_executing){for(let a=s.length-1;a>=0;a--){let l=s[a];if(l.type==="tool"&&l.toolName===e.tool_name&&(e.subtask_id===void 0||l.subtaskId===e.subtask_id)){s[a].status="executing";break}}i();continue}if(e.is_observation){for(let a=s.length-1;a>=0;a--){let l=s[a];if(l.type==="tool"&&l.toolName===e.tool_name&&(e.subtask_id===void 0||l.subtaskId===e.subtask_id)){s[a].status="completed";break}}i();continue}if(e.suggested_actions){P=e.suggested_actions.map(a=>({id:a.action,label:a.label,value:a.action})),i();continue}if(e.is_wave_start){(g||I!=="answer")&&(o(),I="answer"),s.push({type:"wave_start",content:"",waveNumber:e.wave_number,isParallel:!0,waveData:{waveNumber:e.wave_number,subtaskIds:e.subtask_ids||[],parallelCount:e.parallel_count||0,totalWaves:e.total_waves||1}}),i();continue}if(e.is_wave_complete){s.push({type:"wave_complete",content:"",waveNumber:e.wave_number,isParallel:!0,waveData:{waveNumber:e.wave_number,subtaskIds:[],parallelCount:0,totalWaves:0,completedIds:e.completed_ids||[],success:e.success,executionTime:e.execution_time}}),i();continue}if(e.is_parallel_subtask_start){s.push({type:"parallel_subtask_start",content:"",subtaskId:e.subtask_id,waveNumber:e.wave_number,isParallel:!0,parallelSubtaskData:{subtaskId:e.subtask_id,waveNumber:e.wave_number,description:e.description}}),i();continue}if(e.is_parallel_subtask_complete){s.push({type:"parallel_subtask_complete",content:"",subtaskId:e.subtask_id,waveNumber:e.wave_number,isParallel:!0,success:e.success,parallelSubtaskData:{subtaskId:e.subtask_id,waveNumber:e.wave_number,success:e.success,result:e.result,error:e.error,executionTime:e.execution_time}}),i();continue}if(e.is_multi_agent_planning){te=!0,(g||I!=="answer")&&(o(),I="answer"),s.push({type:"multi_agent_planning",content:"",isMultiAgent:!0}),i();continue}if(e.is_reasoning&&e.reasoning_delta){let a=s.findIndex(l=>l.type==="thinking"&&l.isMultiAgent);a>=0?s[a]={...s[a],content:(s[a].content||"")+e.reasoning_delta}:s.push({type:"thinking",content:e.reasoning_delta,isMultiAgent:!0}),i();continue}if(e.is_multi_agent_planning_complete){let a=s.findIndex(l=>l.type==="multi_agent_planning"&&l.isMultiAgent);a>=0?s[a]={...s[a],subagentAllocations:e.subagents||[]}:s.push({type:"multi_agent_planning",content:"",isMultiAgent:!0,subagentAllocations:e.subagents||[]}),i();continue}if(e.is_multi_agent_execution_start)continue;if(e.is_subagent_start){s.push({type:"subagent_start",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,task:e.task,status:"running"}}),i();continue}if(e.is_subagent_progress){let a=s.findIndex(l=>l.type==="subagent_start"&&l.subagentInfo?.id===e.subagent_id);a!==-1&&s[a].subagentInfo&&(s[a]={...s[a],content:e.progress||""}),i();continue}if(e.is_subagent_complete){s.push({type:"subagent_complete",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,status:"completed",result:e.result,executionTime:e.execution_time}}),i();continue}if(e.is_subagent_failed){s.push({type:"subagent_failed",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,status:"failed",error:e.error}}),i();continue}if(e.is_synthesis_start&&te){s.push({type:"synthesis",content:"",isMultiAgent:!0,isSynthesis:!0}),i();continue}if(e.plan_data){let a=e.plan_data;W={goal:a.goal||"",reasoning:a.reasoning||"",subtasks:(a.subtasks||[]).map(l=>({id:Number(l.id),description:l.description,required_tools:l.required_tools,dependencies:l.dependencies,status:"pending"})),total_subtasks:a.subtasks?.length||0,completed_subtasks:0,failed_subtasks:0,progress_percentage:0};}e.subtask_data&&(N=e.subtask_data),e.is_synthesis_start&&(q=!0),e.is_replan&&(J=!0),e.tool_args&&(O=e.tool_args),e.replan_attempt!==void 0&&(H=e.replan_attempt),e.max_replans!==void 0&&(L=e.max_replans),e.failure_reason&&(X=e.failure_reason),e.progress&&(V=e.progress);let r="answer";if(e.is_thinking?r="thinking":e.is_planning||e.is_plan_complete||e.is_replanning?r="planning":e.is_subtask_start||e.is_subtask_complete||e.is_subtask_failed?r="subtask":e.is_progress_update&&(r="progress"),r!==I&&(o(),I=r),e.tool_name&&(S=e.tool_name),e.success!==void 0&&(A=e.success),e.subtask_id!==void 0&&(B=e.subtask_id),r==="thinking"){g+=e.chunk||"";let a=g.match(/"thought"\s*:\s*"((?:[^"\\]|\\.)*)"/);a&&(g=a[1].replace(/\\n/g,`
|
|
8
|
-
`).replace(/\\"/g,'"').replace(/\\t/g," ").replace(/\\\\/g,"\\"));}else if(r==="answer"){let a=e.chunk?.trim()||"",l=f.trim();a&&l&&a===l||(f+=e.chunk||"");}else g+=e.chunk||"";e.previous_message_id&&c.onUserMessageIdUpdate(u,e.previous_message_id),i();}else if(e.type==="claude_text"){f+=e.chunk||"";let r=s.find(a=>a.type==="claude_text");r?r.content+=e.chunk||"":s.push({type:"claude_text",content:e.chunk||"",orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_thinking")s.push({type:"claude_thinking",content:e.content||"",orchestrator:"claude_agent_sdk"}),i();else if(e.type==="claude_file_read"){let r={toolUseId:e.tool_use_id,operation:"read",filePath:e.file_path,status:e.status,content:e.content,totalLines:e.total_lines,language:e.language,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].fileOperationData=r:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_file_edit"){let r={toolUseId:e.tool_use_id,operation:"edit",filePath:e.file_path,status:e.status,oldString:e.old_string,newString:e.new_string,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].fileOperationData=r:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_file_write"){let r={toolUseId:e.tool_use_id,operation:"write",filePath:e.file_path,status:e.status,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].fileOperationData=r:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_bash"){let r={toolUseId:e.tool_use_id,command:e.command,description:e.description,status:e.status,stdout:e.stdout,stderr:e.stderr,exitCode:e.exit_code,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="terminal"&&l.toolUseId===e.tool_use_id);a>=0?s[a].terminalData=r:s.push({type:"terminal",content:"",toolUseId:e.tool_use_id,terminalData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_search"){let r={toolUseId:e.tool_use_id,tool:e.tool,pattern:e.pattern,path:e.path,status:e.status,results:(e.results||[]).map(l=>({filePath:l.file_path,lineNumber:l.line_number,snippet:l.snippet})),totalCount:e.total_count||0,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="search_results"&&l.toolUseId===e.tool_use_id);a>=0?s[a].searchResultsData=r:s.push({type:"search_results",content:"",toolUseId:e.tool_use_id,searchResultsData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_web_search"||e.type==="claude_web_fetch"){let r={toolUseId:e.tool_use_id,operation:e.type==="claude_web_search"?"search":"fetch",query:e.query,url:e.url,status:e.status,results:e.results,content:e.content,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="web_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].webOperationData=r:s.push({type:"web_operation",content:"",toolUseId:e.tool_use_id,webOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_subagent_start"){let r={subagentId:e.subagent_id,subagentType:e.subagent_type,description:e.description,prompt:e.prompt,status:"running",nestedChunks:[]};s.push({type:"subagent",content:"",toolUseId:e.parent_tool_use_id,subagentData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_subagent_chunk"){let r=s.findIndex(a=>a.type==="subagent"&&a.subagentData?.subagentId===e.subagent_id);r>=0&&s[r].subagentData&&s[r].subagentData.nestedChunks.push({type:e.is_tool?"tool":"answer",content:e.chunk||"",toolName:e.tool_name,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_subagent_complete"){let r=s.findIndex(a=>a.type==="subagent"&&a.subagentData?.subagentId===e.subagent_id);r>=0&&s[r].subagentData&&(s[r].subagentData.status="completed",s[r].subagentData.result=e.result,s[r].subagentData.durationMs=e.duration_ms),i();}else if(e.type==="claude_tool_use"||e.type==="claude_tool_result"){let r={toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,toolInput:e.tool_input,status:e.type==="claude_tool_use"?"pending":e.is_error?"error":"completed",content:e.content,isError:e.is_error,durationMs:e.duration_ms},a=s.findIndex(l=>l.claudeToolData?.toolUseId===e.tool_use_id);a>=0?s[a].claudeToolData=r:s.push({type:"tool",content:e.content||"",toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,status:r.status==="pending"?"planned":"completed",claudeToolData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="clarification_needed"){o();let r={question:e.question||"",options:e.options||[],context:e.context,allowFreeText:e.allow_free_text!==!1,subtaskId:e.subtask_id,subtaskDescription:e.subtask_description,subagentName:e.subagent_name,subagentRole:e.subagent_role};s.push({type:"clarification_needed",content:r.question,clarificationData:r,subtaskId:e.subtask_id}),z=r,f||(f=r.question),i();}else if(e.type==="assistant_complete"){o(),ee=!0;let r=e.message?.text_content||f,a=e.message?.id,l=e.message?.metadata?.sources,w=(Date.now()-_)/1e3;c.onComplete(b,r,a,s,P,l,z,w),f=r,a&&(b=a);break}else if(e.type==="client_tool_invocation"&&e.invocation&&c.onToolInvocation)c.onToolInvocation(e.invocation);else {if(e.type==="error")throw new Error(e.error||"Stream error");if(e.type==="done"){if(b&&!ee){o();let r=(Date.now()-_)/1e3;c.onComplete(b,f||"",e.message_id,s,P,void 0,z,r);}else e.message_id&&b&&c.onMessageUpdate({id:b,isStreaming:!1});e.message_id&&(b=e.message_id);break}}}catch(e){if(e instanceof Error&&e.message!=="Stream error"&&(e.message.startsWith("Stream error")||e.message.startsWith("HTTP error")))throw e}}}return {assistantMsgId:b,assistantContent:f}}function Oe(t){let[n,u]=react.useState([]),[c,p]=react.useState(false),[_,f]=react.useState(null),[b,s]=react.useState(null),[P,z]=react.useState(true),[ee,I]=react.useState(null),g=react.useRef(t);g.current=t;let S=react.useRef(b);S.current=b;let F=react.useRef(c);F.current=c;let A=react.useRef(new Map),x=react.useRef(new Map);react.useEffect(()=>{let o=false;async function d(){try{let i=await ue(g.current);o||(s(i),z(!1));}catch(i){o||(I(i instanceof Error?i.message:"Failed to initialize"),z(false));}}return d(),()=>{o=true;}},[t.publicKey,t.assistantId]);let B=react.useMemo(()=>Me(b),[b]),W=chunkKSMAVBLY_cjs.b(B),N=react.useRef(new Map),q=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");let i=await de(g.current,d,o);return N.current.set(i,{id:i,filename:o.name,mimeType:o.type,size:o.size,isImage:o.type.startsWith("image/"),isVideo:o.type.startsWith("video/"),isDocument:!o.type.startsWith("image/")&&!o.type.startsWith("video/")}),i},[]),J=react.useCallback(o=>{N.current.delete(o);},[]),O=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");let{invocation_id:i,tool_name:m,parameters:C}=o;console.log(`[Miiflow] Tool invocation received: "${m}" (id: ${i})`);let h=A.current.get(m);if(!h)return false;try{let k=await Promise.race([h(C),new Promise((j,T)=>setTimeout(()=>T(new Error("Tool execution timeout (30s)")),3e4))]);return console.log(`[Miiflow] Tool "${m}" executed successfully (id: ${i})`),await G(g.current,d,{invocation_id:i,result:k}),console.log(`[Miiflow] Tool result sent for "${m}" (id: ${i})`),!0}catch(k){return console.error(`[Miiflow] Tool '${m}' execution failed:`,k),await G(g.current,d,{invocation_id:i,error:k instanceof Error?k.message:String(k)}),true}},[]);react.useEffect(()=>{if(!b)return;let o=b,d=null,i=null,m=null,C=0,h=false;function k(){if(h)return;let j=Ae(g.current,o);d=new WebSocket(j),d.onopen=()=>{console.log("[Miiflow] WebSocket connected"),C=0,i=setInterval(()=>{d?.readyState===WebSocket.OPEN&&d.send(JSON.stringify({type:"heartbeat"}));},De);},d.onmessage=T=>{try{let M=JSON.parse(T.data);M.type==="client_tool_invocation"&&M.invocation&&O(M.invocation).then(async e=>{if(!e){let r=g.current.onToolInvocationFallback;r&&await r(M.invocation)||G(g.current,o,{invocation_id:M.invocation.invocation_id,error:`No handler found for tool '${M.invocation.tool_name}'`}).catch(console.error);}}).catch(console.error);}catch{}},d.onclose=()=>{if(i&&(clearInterval(i),i=null),!h){let T=Math.min(xe*Math.pow(2,C),ve);C++,console.log(`[Miiflow] WebSocket closed, reconnecting in ${T}ms`),m=setTimeout(k,T);}},d.onerror=T=>{console.error("[Miiflow] WebSocket error:",T);};}return k(),()=>{h=true,i&&clearInterval(i),m&&clearTimeout(m),d&&(d.onclose=null,d.close());}},[b,O]);let H=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");await pe(g.current,d,o);},[]),L=react.useCallback(async(o,d)=>{let i=S.current,m=!!o.trim(),C=d&&d.length>0;if(!m&&!C||F.current||!i)return;let h=`msg-${Date.now()}`,k=d?.map(e=>N.current.get(e)).filter(Boolean),j={id:h,textContent:o,participant:{id:"user",name:g.current.userName||"You",role:"user"},createdAt:new Date().toISOString(),attachments:k?.length?k:void 0};d?.forEach(e=>N.current.delete(e));let T=`assistant-pending-${Date.now()}`,M={id:T,textContent:"",participant:{id:"assistant",name:i.config.branding?.custom_name||i.config.assistant_name,role:"assistant",avatarUrl:i.config.branding?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true};u(e=>[...e,j,M]),p(true),f(T),g.current.onUserMessageCreated?.({id:h,content:o});try{let e=E(g.current),r=await fetch(`${e}/assistant/message/stream/`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:i.config.thread_id,text_content:o,message_id:h,metadata:{},attachment_ids:d||[]})});if(!r.ok)throw new Error(`HTTP error: ${r.status}`);let a=r.body?.getReader();if(!a)throw new Error("No response body");let l=await Ee(a,i,h,{onMessageCreate:w=>{f(w.id),u(D=>[...D.filter(R=>R.id!==T),w]);},onMessageUpdate:w=>{u(D=>D.map(v=>v.id===w.id?{...v,...w}:v));},onUserMessageIdUpdate:(w,D)=>{u(v=>v.map(R=>R.id===w?{...R,id:D}:R));},onComplete:(w,D,v,R,ae,_e,be,we)=>{w&&u(ye=>ye.map(se=>se.id===w?{...se,id:v||se.id,textContent:D,isStreaming:!1,reasoning:R,suggestedActions:ae,citations:_e,pendingClarification:be,executionTime:we}:se)),g.current.onAssistantMessageComplete?.({id:v||w||"",content:D});},onToolInvocation:async w=>{if(!await O(w)){let v=g.current.onToolInvocationFallback;if(!(v?await v(w):!1)){let ae=S.current;ae&&await G(g.current,ae,{invocation_id:w.invocation_id,error:`No handler found for tool '${w.tool_name}'`});}}}});l.assistantMsgId&&u(w=>w.map(D=>D.id===l.assistantMsgId?{...D,isStreaming:!1}:D));}catch(e){console.error("[Miiflow] Send error:",e);let r=S.current,a={id:`error-${Date.now()}`,textContent:"Sorry, I encountered an error. Please try again.",participant:{id:"assistant",name:r?.config.branding?.custom_name||r?.config.assistant_name||"Assistant",role:"assistant",avatarUrl:r?.config.branding?.assistant_avatar},createdAt:new Date().toISOString()};u(l=>[...l.filter(w=>w.id!==T),a]),I(e instanceof Error?e.message:"Send failed");}finally{p(false),f(null);}},[O]),X=react.useCallback(async()=>{let o=S.current;if(!o)throw new Error("Not initialized");let d=await ce(g.current,o);d.token||console.warn("[Miiflow] CreateThread did not return new token \u2014 tools may register to wrong thread");let i={...o,config:{...o.config,thread_id:d.threadId},token:d.token||o.token};if(S.current=i,s(i),u([]),x.current.size>0){console.log(`[Miiflow] Re-registering ${x.current.size} tools on new thread`);try{await Q(g.current,i,Array.from(x.current.values()));}catch(m){console.warn("[Miiflow] Failed to re-register tools:",m);}}return d.threadId},[]),V=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");ie(o),A.current.set(o.name,o.handler);let i=re(o);x.current.set(o.name,i);try{await Q(g.current,d,[i]),console.log(`[Miiflow] Tool registered: "${o.name}"`);}catch(m){throw A.current.delete(o.name),x.current.delete(o.name),m}},[]),te=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");for(let h of o)ie(h);let i=new Map(A.current),m=new Map(x.current),C=[];for(let h of o){A.current.set(h.name,h.handler);let k=re(h);x.current.set(h.name,k),C.push(k);}try{await Q(g.current,d,C);let h=o.map(k=>k.name);console.log(`[Miiflow] Tools registered: ${JSON.stringify(h)} (${o.length} tools)`);}catch(h){throw A.current=i,x.current=m,h}},[]),Z=react.useMemo(()=>n.map(o=>({id:o.id,textContent:o.textContent?.replace(/\[ref:[^\]]+\]/g,"")||o.textContent,participant:o.participant,createdAt:o.createdAt,isStreaming:o.isStreaming,reasoning:o.reasoning,suggestedActions:o.suggestedActions,citations:o.citations,attachments:o.attachments,pendingClarification:o.pendingClarification,executionTime:o.executionTime})),[n]),ne=react.useCallback(o=>{s(o);},[]);return {messages:Z,isStreaming:c,streamingMessageId:_,sendMessage:L,uploadFile:q,removeUploadedAttachment:J,session:b,loading:P,error:ee,branding:B,brandingCSSVars:W,startNewThread:X,registerTool:V,registerTools:te,sendSystemEvent:H,handleToolInvocation:O,updateSession:ne}}function le(t){try{let n=t.split(".");if(n.length!==3)return null;let u=n[1].replace(/-/g,"+").replace(/_/g,"/"),c=atob(u),p=JSON.parse(c);return typeof p.exp=="number"?p.exp*1e3:null}catch{return null}}function Pe(t,n){let u=le(t);return u===null?true:u-Date.now()<=n}function Ne(t){let n=le(t);return n===null?true:Date.now()>=n}function Ue(t){let n=le(t);return n===null?0:Math.max(0,n-Date.now())}exports.ToolValidationError=y;exports.createThread=ce;exports.getBackendBaseUrl=E;exports.getOrCreateUserId=U;exports.getTimeUntilExpiry=Ue;exports.initSession=ue;exports.isTokenExpired=Ne;exports.isTokenExpiringSoon=Pe;exports.parseTokenExpiry=le;exports.registerToolsOnBackend=Q;exports.sendSystemEvent=pe;exports.sendToolResult=G;exports.serializeToolDefinition=re;exports.updateUser=ke;exports.uploadFile=de;exports.useMiiflowChat=Oe;exports.validateToolDefinition=ie;//# sourceMappingURL=index.cjs.map
|
|
9
|
-
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/session.ts","../../src/client/tool-validator.ts","../../src/client/useMiiflowChat.ts","../../src/client/token-utils.ts"],"names":["getBackendBaseUrl","config","getOrCreateUserId","key","userId","initSession","backendBaseUrl","response","errorText","data","createThread","session","result","newThreadId","updateUser","userData","uploadFile","file","uploadUrl","formData","attachmentId","sendSystemEvent","systemEvent","sendToolResult","responseData","registerToolsOnBackend","toolDefinitions","VALID_JSON_TYPES","TOOL_NAME_PATTERN","ToolValidationError","message","validateToolDefinition","tool","validateToolName","validateDescription","validateParametersSchema","name","description","schema","propName","propSchema","validatePropertySchema","item","types","type","nestedPropName","nestedPropSchema","itemSchema","index","serializeToolDefinition","WS_HEARTBEAT_INTERVAL","WS_RECONNECT_BASE_DELAY","WS_RECONNECT_MAX_DELAY","buildWebSocketUrl","url","wsOrigin","mapSessionBranding","b","parseSSEStream","reader","optimisticId","callbacks","decoder","streamStartTime","assistantContent","assistantMsgId","chunks","suggestedActions","pendingClarification","receivedComplete","currentChunkType","currentChunkContent","currentToolName","currentToolDescription","currentSuccess","currentToolStatus","currentSubtaskId","currentPlanData","currentSubtaskData","currentIsSynthesis","currentIsReplan","currentToolArgs","currentReplanAttempt","currentMaxReplans","currentFailureReason","currentProgress","isMultiAgentMode","lineBuffer","branding","finalizeChunk","buildDisplayChunks","display","c","updateStreamingMessage","displayChunks","assistantMsg","done","value","rawChunk","lines","line","parsed","i","chunk","existingIdx","planningIdx","subagentIndex","backendPlan","st","newChunkType","match","chunkTrimmed","accumulatedTrimmed","existingTextChunk","fileOpData","fileEditData","fileWriteData","termData","searchData","r","webOpData","subData","subagentIdx","claudeToolData","clarificationData","finalContent","finalId","sources","elapsedSeconds","elapsedSecondsDone","useMiiflowChat","messages","setMessages","useState","isStreaming","setIsStreaming","streamingMessageId","setStreamingMessageId","setSession","loading","setLoading","error","setError","configRef","useRef","sessionRef","isStreamingRef","toolHandlersRef","toolDefinitionsRef","useEffect","cancelled","init","sess","err","useMemo","brandingCSSVars","useBrandingCSSVars","uploadedAttachmentsRef","useCallback","currentSession","removeUploadedAttachment","handleToolInvocation","invocation","invocation_id","tool_name","parameters","handler","_","reject","ws","heartbeatTimer","reconnectTimer","reconnectAttempt","disposed","connect","event","handled","fallback","delay","sendMessage","content","attachmentIds","hasText","hasAttachments","messageAttachments","id","userMessage","placeholderAssistantId","placeholderAssistant","prev","msg","m","update","oldId","newId","executionTime","errorMsg","startNewThread","updatedSession","registerTool","serialized","registerTools","tools","previousHandlers","previousDefinitions","serializedTools","toolNames","t","chatMessages","updateSession","newSession","parseTokenExpiry","token","parts","base64","jsonPayload","decoded","isTokenExpiringSoon","thresholdMs","expiry","isTokenExpired","getTimeUntilExpiry"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Session initialization and management for Miiflow embedded chat.\n */\n\nimport type { EmbedSession, MiiflowChatConfig, SystemEvent, ToolExecutionResult } from \"./types\";\n\n/**\n * Determine the backend base URL from config.\n */\nexport function getBackendBaseUrl(config: MiiflowChatConfig): string {\n\tif (config.baseUrl) return config.baseUrl.replace(/\\/api\\/?$/, \"\");\n\n\tconst isDev =\n\t\tconfig.bundleUrl?.includes(\"localhost\") ||\n\t\tconfig.bundleUrl?.includes(\"127.0.0.1\") ||\n\t\tfalse;\n\treturn isDev ? \"http://localhost:8003\" : \"https://api.miiflow.ai\";\n}\n\n/**\n * Get or create a persistent anonymous user ID stored in localStorage.\n */\nexport function getOrCreateUserId(): string {\n\tconst key = \"miiflow-user-id\";\n\tlet userId: string | null = null;\n\ttry {\n\t\tuserId = localStorage.getItem(key);\n\t} catch {\n\t\t// localStorage may be unavailable (e.g. sandboxed iframe)\n\t}\n\tif (!userId) {\n\t\tuserId = `muid_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n\t\ttry {\n\t\t\tlocalStorage.setItem(key, userId);\n\t\t} catch {\n\t\t\t// Ignore storage errors\n\t\t}\n\t}\n\treturn userId;\n}\n\n/**\n * Initialize an embed session by calling the backend init endpoint.\n */\nexport async function initSession(config: MiiflowChatConfig): Promise<EmbedSession> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\n\tconst response = await fetch(`${backendBaseUrl}/api/embed/init`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"X-Embed-Public-Key\": config.publicKey,\n\t\t\t\"x-mii-user-id\": getOrCreateUserId(),\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tassistant_id: config.assistantId,\n\t\t\tuser_data: {\n\t\t\t\tuser_id: config.userId,\n\t\t\t\tname: config.userName,\n\t\t\t\temail: config.userEmail,\n\t\t\t},\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tthrow new Error(`Init failed: ${response.status} - ${errorText}`);\n\t}\n\n\tconst data = await response.json();\n\tif (!data.success) {\n\t\tthrow new Error(data.error || \"Failed to initialize session\");\n\t}\n\n\treturn {\n\t\ttoken: data.token,\n\t\tconfig: data.config,\n\t\tsession_id: data.session_id,\n\t};\n}\n\n/**\n * Create a new thread for the current session.\n */\nexport async function createThread(\n\tconfig: MiiflowChatConfig,\n\tsession: EmbedSession,\n): Promise<{ threadId: string; token?: string }> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\n\tconst response = await fetch(`${backendBaseUrl}/api/embed/graphql`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t\t\"x-mii-user-id\": getOrCreateUserId(),\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\toperationName: \"CreateThread\",\n\t\t\tvariables: {\n\t\t\t\tinput: {\n\t\t\t\t\tassistantId: session.config.assistant_id,\n\t\t\t\t\tname: \"New Thread\",\n\t\t\t\t\tisPreview: false,\n\t\t\t\t},\n\t\t\t},\n\t\t\tquery: `mutation CreateThread($input: CreateThreadInput!) {\n createThread(input: $input) {\n thread { id status name isPreview }\n }\n }`,\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to create thread: ${response.status}`);\n\t}\n\n\tconst result = await response.json();\n\tconst newThreadId = result.data?.createThread?.thread?.id;\n\n\tif (!newThreadId) {\n\t\tthrow new Error(\"No thread ID returned\");\n\t}\n\n\treturn { threadId: newThreadId, token: result.token };\n}\n\n/**\n * Update user data for the current session.\n */\nexport async function updateUser(\n\tconfig: MiiflowChatConfig,\n\tsession: EmbedSession,\n\tuserData: { user_id?: string; name?: string; email?: string },\n): Promise<void> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\n\tawait fetch(`${backendBaseUrl}/api/embed/update`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t},\n\t\tbody: JSON.stringify({ user_data: userData }),\n\t});\n}\n\n/**\n * Upload a file attachment via REST endpoint.\n * Returns the attachment ID for use in sendMessage.\n */\nexport async function uploadFile(config: MiiflowChatConfig, session: EmbedSession, file: File): Promise<string> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\tconst uploadUrl = `${backendBaseUrl}/api/embed/upload-attachment`;\n\n\tconst formData = new FormData();\n\tformData.append(\"file\", file);\n\n\tconst response = await fetch(uploadUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t\t\"x-mii-user-id\": getOrCreateUserId(),\n\t\t},\n\t\tbody: formData,\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tthrow new Error(`Upload failed: ${response.status} - ${errorText}`);\n\t}\n\n\tconst json = await response.json();\n\tconst attachmentId = json.attachment?.id;\n\n\tif (!attachmentId) {\n\t\tthrow new Error(\"No attachment ID returned\");\n\t}\n\n\treturn attachmentId;\n}\n\n/**\n * Send a system event to the backend (invisible to chat, processed by assistant).\n */\nexport async function sendSystemEvent(\n\tconfig: MiiflowChatConfig,\n\tsession: EmbedSession,\n\tsystemEvent: SystemEvent,\n): Promise<void> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\n\tconst response = await fetch(`${backendBaseUrl}/api/embed/system-event`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t\t\"x-mii-user-id\": getOrCreateUserId(),\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tthread_id: session.config.thread_id,\n\t\t\tsystem_event: {\n\t\t\t\taction: systemEvent.action,\n\t\t\t\tdescription: systemEvent.description,\n\t\t\t\tfollowUpInstruction: systemEvent.followUpInstruction,\n\t\t\t\tmetadata: systemEvent.metadata || {},\n\t\t\t},\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tthrow new Error(`Failed to send system event: ${response.status} - ${errorText}`);\n\t}\n\n\tconst result = await response.json();\n\tif (!result.success) {\n\t\tthrow new Error(result.error || \"Failed to send system event\");\n\t}\n}\n\n/**\n * Send a tool execution result back to the backend.\n */\nexport async function sendToolResult(\n\tconfig: MiiflowChatConfig,\n\tsession: EmbedSession,\n\tresult: ToolExecutionResult,\n): Promise<void> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\n\tconst response = await fetch(`${backendBaseUrl}/api/embed/tool-result`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t},\n\t\tbody: JSON.stringify(result),\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tthrow new Error(`Failed to send tool result: ${response.status} - ${errorText}`);\n\t}\n\n\tconst responseData = await response.json();\n\tif (!responseData.success) {\n\t\tthrow new Error(`Failed to send tool result: ${responseData.error}`);\n\t}\n}\n\n/**\n * Register tool definitions with the backend.\n */\nexport async function registerToolsOnBackend(\n\tconfig: MiiflowChatConfig,\n\tsession: EmbedSession,\n\ttoolDefinitions: Array<Omit<import(\"./types\").ClientToolDefinition, \"handler\">>,\n): Promise<void> {\n\tconst backendBaseUrl = getBackendBaseUrl(config);\n\n\tif (toolDefinitions.length === 1) {\n\t\tconst response = await fetch(`${backendBaseUrl}/api/embed/register-tool`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t\t},\n\t\t\tbody: JSON.stringify(toolDefinitions[0]),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`Failed to register tool: ${response.status} - ${errorText}`);\n\t\t}\n\t\tconst data = await response.json();\n\t\tif (!data.success) {\n\t\t\tthrow new Error(`Failed to register tool: ${data.error || \"Unknown error\"}`);\n\t\t}\n\t} else if (toolDefinitions.length > 1) {\n\t\tconst response = await fetch(`${backendBaseUrl}/api/embed/register-tools`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${session.token}`,\n\t\t\t},\n\t\t\tbody: JSON.stringify(toolDefinitions),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`Failed to register tools: ${response.status} - ${errorText}`);\n\t\t}\n\t\tconst data = await response.json();\n\t\tif (!data.success) {\n\t\t\tthrow new Error(`Failed to register tools: ${data.error || \"Unknown error\"}`);\n\t\t}\n\t}\n}\n","/**\n * Client-side validator for tool definitions.\n * Validates tool definitions before they're sent to the backend.\n */\n\nimport type {\n ClientToolDefinition,\n JSONSchemaProperty,\n JSONSchemaObject,\n} from \"./types\";\n\nconst MAX_TOOL_NAME_LENGTH = 64;\nconst MAX_DESCRIPTION_LENGTH = 500;\nconst VALID_JSON_TYPES = new Set([\n \"string\",\n \"number\",\n \"integer\",\n \"boolean\",\n \"array\",\n \"object\",\n \"null\",\n]);\nconst TOOL_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n\nexport class ToolValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ToolValidationError\";\n }\n}\n\n/**\n * Validates a client tool definition.\n * Throws ToolValidationError if validation fails.\n */\nexport function validateToolDefinition(tool: ClientToolDefinition): void {\n if (!tool.name) {\n throw new ToolValidationError(\"Tool name is required\");\n }\n if (!tool.description) {\n throw new ToolValidationError(\"Tool description is required\");\n }\n if (!tool.parameters) {\n throw new ToolValidationError(\"Tool parameters schema is required\");\n }\n if (typeof tool.handler !== \"function\") {\n throw new ToolValidationError(\"Tool handler must be a function\");\n }\n\n validateToolName(tool.name);\n validateDescription(tool.description);\n validateParametersSchema(tool.parameters);\n}\n\nfunction validateToolName(name: string): void {\n if (typeof name !== \"string\") {\n throw new ToolValidationError(\"Tool name must be a string\");\n }\n if (name.length === 0) {\n throw new ToolValidationError(\"Tool name cannot be empty\");\n }\n if (name.length > MAX_TOOL_NAME_LENGTH) {\n throw new ToolValidationError(\n `Tool name too long (max ${MAX_TOOL_NAME_LENGTH} characters)`\n );\n }\n if (!TOOL_NAME_PATTERN.test(name)) {\n throw new ToolValidationError(\n \"Tool name must start with letter/underscore and contain only alphanumeric characters and underscores\"\n );\n }\n}\n\nfunction validateDescription(description: string): void {\n if (typeof description !== \"string\") {\n throw new ToolValidationError(\"Tool description must be a string\");\n }\n if (description.trim().length === 0) {\n throw new ToolValidationError(\"Tool description cannot be empty\");\n }\n if (description.length > MAX_DESCRIPTION_LENGTH) {\n throw new ToolValidationError(\n `Tool description too long (max ${MAX_DESCRIPTION_LENGTH} characters)`\n );\n }\n}\n\nfunction validateParametersSchema(schema: JSONSchemaObject): void {\n if (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n throw new ToolValidationError(\"Parameters must be a JSON Schema object\");\n }\n if (schema.type !== \"object\") {\n throw new ToolValidationError(\n \"Parameters schema must be of type 'object' (function parameters)\"\n );\n }\n\n if (schema.properties && typeof schema.properties === \"object\") {\n for (const [propName, propSchema] of Object.entries(schema.properties)) {\n validatePropertySchema(propName, propSchema);\n }\n }\n\n if (schema.required !== undefined) {\n if (!Array.isArray(schema.required)) {\n throw new ToolValidationError(\"'required' must be an array\");\n }\n for (const item of schema.required) {\n if (typeof item !== \"string\") {\n throw new ToolValidationError(\n \"'required' array must contain only strings\"\n );\n }\n }\n }\n\n if (schema.additionalProperties !== undefined) {\n if (\n typeof schema.additionalProperties !== \"boolean\" &&\n (typeof schema.additionalProperties !== \"object\" ||\n schema.additionalProperties === null)\n ) {\n throw new ToolValidationError(\n \"'additionalProperties' must be boolean or object\"\n );\n }\n }\n}\n\nfunction validatePropertySchema(\n propName: string,\n schema: JSONSchemaProperty\n): void {\n if (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n throw new ToolValidationError(\n `Property '${propName}' schema must be an object`\n );\n }\n\n if (schema.type !== undefined) {\n const types = Array.isArray(schema.type) ? schema.type : [schema.type];\n for (const type of types) {\n if (!VALID_JSON_TYPES.has(type)) {\n throw new ToolValidationError(\n `Invalid type '${type}' for property '${propName}'. ` +\n `Valid types: ${Array.from(VALID_JSON_TYPES).join(\", \")}`\n );\n }\n }\n }\n\n if (schema.enum !== undefined && !Array.isArray(schema.enum)) {\n throw new ToolValidationError(\n `Property '${propName}' enum must be an array`\n );\n }\n\n if (schema.properties && typeof schema.properties === \"object\") {\n for (const [nestedPropName, nestedPropSchema] of Object.entries(\n schema.properties\n )) {\n validatePropertySchema(`${propName}.${nestedPropName}`, nestedPropSchema);\n }\n }\n\n if (schema.items) {\n if (Array.isArray(schema.items)) {\n schema.items.forEach((itemSchema, index) => {\n validatePropertySchema(`${propName}[${index}]`, itemSchema);\n });\n } else {\n validatePropertySchema(`${propName}[]`, schema.items);\n }\n }\n}\n\n/**\n * Strips the handler function from a tool definition for sending to backend.\n */\nexport function serializeToolDefinition(\n tool: ClientToolDefinition\n): Omit<ClientToolDefinition, \"handler\"> {\n return {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n };\n}\n","/**\n * useMiiflowChat - React hook for connecting to Miiflow's embedded chat API.\n *\n * Handles session init, SSE streaming, message management, tool registration,\n * and branding. Returns a shape directly compatible with ChatProvider props.\n */\n\nimport { useState, useCallback, useEffect, useRef, useMemo } from \"react\";\nimport type {\n ChatMessage,\n ParticipantRole,\n StreamingChunk,\n ClarificationData,\n ProgressData,\n FileOperationChunkData,\n TerminalChunkData,\n SearchResultsChunkData,\n WebOperationChunkData,\n SubagentChunkData,\n ClaudeToolChunkData,\n} from \"../types\";\nimport type { BrandingData } from \"../types/branding\";\nimport type {\n MiiflowChatConfig,\n MiiflowChatResult,\n EmbedSession,\n ClientToolDefinition,\n ToolHandler,\n ToolInvocationRequest,\n SystemEvent,\n} from \"./types\";\nimport {\n initSession,\n getBackendBaseUrl,\n getOrCreateUserId,\n createThread,\n registerToolsOnBackend,\n uploadFile as uploadFileToBackend,\n sendSystemEvent as sendSystemEventToBackend,\n sendToolResult,\n} from \"./session\";\nimport { validateToolDefinition, serializeToolDefinition } from \"./tool-validator\";\nimport { useBrandingCSSVars } from \"../hooks/use-branding-css-vars\";\n\n// ============================================================================\n// WebSocket helpers\n// ============================================================================\n\nconst WS_HEARTBEAT_INTERVAL = 21000; // 21 seconds — matches web app\nconst WS_RECONNECT_BASE_DELAY = 1000;\nconst WS_RECONNECT_MAX_DELAY = 30000;\n\nfunction buildWebSocketUrl(config: MiiflowChatConfig, session: EmbedSession): string {\n if (config.webSocketUrl) {\n const url = new URL(config.webSocketUrl);\n url.pathname = `/ws/assistant/thread/${session.config.thread_id}/`;\n url.searchParams.set(\"role\", \"user\");\n url.searchParams.set(\"user_id\", getOrCreateUserId());\n url.searchParams.set(\"embed_token\", session.token);\n return url.toString();\n }\n\n const baseUrl = getBackendBaseUrl(config);\n // Strip /api suffix to get host origin, then convert protocol\n const origin = baseUrl.replace(/\\/api$/, \"\");\n const wsOrigin = origin.replace(/^https:/, \"wss:\").replace(/^http:/, \"ws:\");\n const userId = getOrCreateUserId();\n return `${wsOrigin}/ws/assistant/thread/${session.config.thread_id}/?role=user&user_id=${encodeURIComponent(userId)}&embed_token=${encodeURIComponent(session.token)}`;\n}\n\n// ============================================================================\n// Internal types\n// ============================================================================\n\ninterface InternalMessage {\n id: string;\n textContent: string;\n participant: {\n id: string;\n name: string;\n role: ParticipantRole;\n avatarUrl?: string;\n };\n createdAt: string;\n isStreaming?: boolean;\n reasoning?: StreamingChunk[];\n suggestedActions?: Array<{ id: string; label: string; value: string }>;\n citations?: import(\"../types\").SourceReference[];\n attachments?: import(\"../types\").Attachment[];\n pendingClarification?: ClarificationData;\n /** Wall-clock execution time in seconds, persisted after streaming completes */\n executionTime?: number;\n}\n\ntype ChunkType =\n | \"answer\"\n | \"thinking\"\n | \"tool\"\n | \"observation\"\n | \"planning\"\n | \"subtask\"\n | \"progress\"\n | \"clarification_needed\"\n // Multi-Agent\n | \"multi_agent_planning\"\n | \"subagent_start\"\n | \"subagent_complete\"\n | \"subagent_failed\"\n | \"synthesis\"\n // Claude SDK\n | \"claude_text\"\n | \"claude_thinking\"\n | \"subagent\"\n | \"file_operation\"\n | \"terminal\"\n | \"search_results\"\n | \"web_operation\";\n\ninterface AccumulatedChunk {\n type: string;\n content: string;\n toolName?: string;\n toolDescription?: string;\n status?: string;\n success?: boolean;\n subtaskId?: number;\n clarificationData?: ClarificationData;\n // Plan & Execute metadata\n planData?: import(\"../types\").PlanData;\n subtaskData?: import(\"../types\").SubTaskData;\n isSynthesis?: boolean;\n isReplan?: boolean;\n // Parallel plan fields\n waveData?: import(\"../types\").WaveData;\n parallelSubtaskData?: import(\"../types\").ParallelSubtaskData;\n waveNumber?: number;\n isParallel?: boolean;\n // Multi-Agent fields\n isMultiAgent?: boolean;\n subagentInfo?: import(\"../types\").SubagentInfo;\n subagentAllocations?: { name: string; focus: string; query?: string }[];\n // Missing data fields (Gap C)\n toolArgs?: Record<string, unknown>;\n replanAttempt?: number;\n maxReplans?: number;\n failureReason?: string;\n progress?: ProgressData;\n // Claude SDK fields\n orchestrator?: string;\n toolUseId?: string;\n subagentData?: SubagentChunkData;\n fileOperationData?: FileOperationChunkData;\n terminalData?: TerminalChunkData;\n searchResultsData?: SearchResultsChunkData;\n webOperationData?: WebOperationChunkData;\n claudeToolData?: ClaudeToolChunkData;\n}\n\n// ============================================================================\n// Branding mapper\n// ============================================================================\n\nfunction mapSessionBranding(\n session: EmbedSession | null\n): BrandingData | null {\n const b = session?.config.branding;\n if (!b) return null;\n return {\n customName: b.custom_name,\n messageFontSize: b.message_font_size,\n welcomeMessage: b.welcome_message,\n chatboxPlaceholder: b.chatbox_placeholder,\n backgroundBubbleColor: b.background_bubble_color,\n headerBackgroundColor: b.header_background_color,\n showHeader: b.show_header,\n rotatingPlaceholders: b.rotating_placeholders,\n presetQuestions: b.preset_questions,\n chatbotLogo: b.chatbot_logo,\n assistantAvatar: b.assistant_avatar,\n };\n}\n\n// ============================================================================\n// SSE stream parser\n// ============================================================================\n\ninterface StreamParseCallbacks {\n onMessageUpdate: (msg: Partial<InternalMessage> & { id: string }) => void;\n onMessageCreate: (msg: InternalMessage) => void;\n onUserMessageIdUpdate: (optimisticId: string, newId: string) => void;\n onComplete: (\n assistantMsgId: string | null,\n finalContent: string,\n finalId?: string,\n chunks?: StreamingChunk[],\n suggestedActions?: Array<{ id: string; label: string; value: string }>,\n sources?: any[],\n pendingClarification?: ClarificationData,\n executionTime?: number\n ) => void;\n onToolInvocation?: (invocation: ToolInvocationRequest) => void;\n}\n\nasync function parseSSEStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n session: EmbedSession,\n optimisticId: string,\n callbacks: StreamParseCallbacks\n): Promise<{ assistantMsgId: string | null; assistantContent: string }> {\n const decoder = new TextDecoder();\n const streamStartTime = Date.now();\n let assistantContent = \"\";\n let assistantMsgId: string | null = null;\n const chunks: AccumulatedChunk[] = [];\n let suggestedActions:\n | Array<{ id: string; label: string; value: string }>\n | undefined;\n let pendingClarification: ClarificationData | undefined;\n let receivedComplete = false;\n\n // Chunk accumulation state\n let currentChunkType: ChunkType = \"answer\";\n let currentChunkContent = \"\";\n let currentToolName: string | undefined;\n let currentToolDescription: string | undefined;\n let currentSuccess: boolean | undefined;\n let currentToolStatus: \"planned\" | \"executing\" | \"completed\" | undefined;\n let currentSubtaskId: number | undefined;\n // Plan & Execute metadata (preserved through finalizeChunk)\n let currentPlanData: import(\"../types\").PlanData | undefined;\n let currentSubtaskData: import(\"../types\").SubTaskData | undefined;\n let currentIsSynthesis: boolean | undefined;\n let currentIsReplan: boolean | undefined;\n // Missing data fields (Gap C)\n let currentToolArgs: Record<string, unknown> | undefined;\n let currentReplanAttempt: number | undefined;\n let currentMaxReplans: number | undefined;\n let currentFailureReason: string | undefined;\n let currentProgress: ProgressData | undefined;\n // Multi-agent tracking\n let isMultiAgentMode = false;\n\n let lineBuffer = \"\";\n\n const branding = session.config.branding;\n\n const finalizeChunk = () => {\n if (currentChunkContent || currentChunkType === \"tool\") {\n chunks.push({\n type: currentChunkType,\n content: currentChunkContent,\n toolName: currentToolName,\n toolDescription: currentToolDescription,\n success: currentSuccess,\n status: currentToolStatus,\n subtaskId: currentSubtaskId,\n planData: currentPlanData,\n subtaskData: currentSubtaskData,\n isSynthesis: currentIsSynthesis,\n isReplan: currentIsReplan,\n toolArgs: currentToolArgs,\n replanAttempt: currentReplanAttempt,\n maxReplans: currentMaxReplans,\n failureReason: currentFailureReason,\n progress: currentProgress,\n });\n currentChunkContent = \"\";\n currentToolName = undefined;\n currentToolDescription = undefined;\n currentSuccess = undefined;\n currentToolStatus = undefined;\n currentSubtaskId = undefined;\n currentPlanData = undefined;\n currentSubtaskData = undefined;\n currentIsSynthesis = undefined;\n currentIsReplan = undefined;\n currentToolArgs = undefined;\n currentReplanAttempt = undefined;\n currentMaxReplans = undefined;\n currentFailureReason = undefined;\n currentProgress = undefined;\n }\n };\n\n const buildDisplayChunks = (): StreamingChunk[] => {\n const display = chunks.map((c) => c as unknown as StreamingChunk);\n if (currentChunkContent || currentChunkType === \"tool\") {\n display.push({\n type: currentChunkType as StreamingChunk[\"type\"],\n content: currentChunkContent,\n toolName: currentToolName,\n toolDescription: currentToolDescription,\n success: currentSuccess,\n status: currentToolStatus as StreamingChunk[\"status\"],\n subtaskId: currentSubtaskId,\n planData: currentPlanData,\n subtaskData: currentSubtaskData,\n isSynthesis: currentIsSynthesis,\n isReplan: currentIsReplan,\n toolArgs: currentToolArgs,\n replanAttempt: currentReplanAttempt,\n maxReplans: currentMaxReplans,\n failureReason: currentFailureReason,\n progress: currentProgress,\n });\n }\n return display;\n };\n\n const updateStreamingMessage = () => {\n const displayChunks = buildDisplayChunks();\n\n if (!assistantMsgId) {\n assistantMsgId = `assistant-${Date.now()}`;\n const assistantMsg: InternalMessage = {\n id: assistantMsgId,\n textContent: assistantContent,\n participant: {\n id: \"assistant\",\n name:\n branding?.custom_name || session.config.assistant_name,\n role: \"assistant\",\n avatarUrl: branding?.assistant_avatar,\n },\n createdAt: new Date().toISOString(),\n isStreaming: true,\n reasoning: displayChunks,\n suggestedActions,\n };\n callbacks.onMessageCreate(assistantMsg);\n } else {\n callbacks.onMessageUpdate({\n id: assistantMsgId,\n textContent: assistantContent,\n reasoning: displayChunks,\n suggestedActions,\n });\n }\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const rawChunk = decoder.decode(value, { stream: true });\n const text = lineBuffer + rawChunk;\n const lines = text.split(\"\\n\");\n\n if (!rawChunk.endsWith(\"\\n\")) {\n lineBuffer = lines.pop() || \"\";\n } else {\n lineBuffer = \"\";\n }\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n\n const data = line.slice(6);\n if (data === \"[DONE]\") break;\n\n try {\n const parsed = JSON.parse(data);\n\n if (parsed.type === \"assistant_chunk\") {\n // Handle tool planned\n if (parsed.is_tool_planned) {\n if (currentChunkContent || currentChunkType !== \"answer\") {\n finalizeChunk();\n currentChunkType = \"answer\";\n }\n\n chunks.push({\n type: \"tool\",\n content: \"\",\n toolName: parsed.tool_name,\n toolDescription: parsed.tool_description,\n status: \"planned\",\n subtaskId: parsed.subtask_id,\n });\n updateStreamingMessage();\n continue;\n }\n\n // Handle tool executing\n if (parsed.is_tool_executing) {\n for (let i = chunks.length - 1; i >= 0; i--) {\n const chunk = chunks[i];\n if (\n chunk.type === \"tool\" &&\n chunk.toolName === parsed.tool_name &&\n (parsed.subtask_id === undefined ||\n chunk.subtaskId === parsed.subtask_id)\n ) {\n chunks[i].status = \"executing\";\n break;\n }\n }\n updateStreamingMessage();\n continue;\n }\n\n // Handle observation\n if (parsed.is_observation) {\n for (let i = chunks.length - 1; i >= 0; i--) {\n const chunk = chunks[i];\n if (\n chunk.type === \"tool\" &&\n chunk.toolName === parsed.tool_name &&\n (parsed.subtask_id === undefined ||\n chunk.subtaskId === parsed.subtask_id)\n ) {\n chunks[i].status = \"completed\";\n break;\n }\n }\n updateStreamingMessage();\n continue;\n }\n\n // Handle suggested actions\n if (parsed.suggested_actions) {\n suggestedActions = parsed.suggested_actions.map(\n (a: { action: string; label: string }) => ({\n id: a.action,\n label: a.label,\n value: a.action,\n })\n );\n updateStreamingMessage();\n continue;\n }\n\n // Handle wave/parallel execution events\n if (parsed.is_wave_start) {\n if (currentChunkContent || currentChunkType !== \"answer\") {\n finalizeChunk();\n currentChunkType = \"answer\";\n }\n chunks.push({\n type: \"wave_start\",\n content: \"\",\n waveNumber: parsed.wave_number,\n isParallel: true,\n waveData: {\n waveNumber: parsed.wave_number,\n subtaskIds: parsed.subtask_ids || [],\n parallelCount: parsed.parallel_count || 0,\n totalWaves: parsed.total_waves || 1,\n },\n } as unknown as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_wave_complete) {\n chunks.push({\n type: \"wave_complete\",\n content: \"\",\n waveNumber: parsed.wave_number,\n isParallel: true,\n waveData: {\n waveNumber: parsed.wave_number,\n subtaskIds: [],\n parallelCount: 0,\n totalWaves: 0,\n completedIds: parsed.completed_ids || [],\n success: parsed.success,\n executionTime: parsed.execution_time,\n },\n } as unknown as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_parallel_subtask_start) {\n chunks.push({\n type: \"parallel_subtask_start\",\n content: \"\",\n subtaskId: parsed.subtask_id,\n waveNumber: parsed.wave_number,\n isParallel: true,\n parallelSubtaskData: {\n subtaskId: parsed.subtask_id,\n waveNumber: parsed.wave_number,\n description: parsed.description,\n },\n } as unknown as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_parallel_subtask_complete) {\n chunks.push({\n type: \"parallel_subtask_complete\",\n content: \"\",\n subtaskId: parsed.subtask_id,\n waveNumber: parsed.wave_number,\n isParallel: true,\n success: parsed.success,\n parallelSubtaskData: {\n subtaskId: parsed.subtask_id,\n waveNumber: parsed.wave_number,\n success: parsed.success,\n result: parsed.result,\n error: parsed.error,\n executionTime: parsed.execution_time,\n },\n } as unknown as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n // ============================================\n // Multi-Agent Event Handlers (miiflow-llm orchestrator)\n // ============================================\n\n if (parsed.is_multi_agent_planning) {\n isMultiAgentMode = true;\n if (currentChunkContent || currentChunkType !== \"answer\") {\n finalizeChunk();\n currentChunkType = \"answer\";\n }\n chunks.push({\n type: \"multi_agent_planning\",\n content: \"\",\n isMultiAgent: true,\n } as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_reasoning && parsed.reasoning_delta) {\n // Multi-agent planning reasoning — accumulate into a thinking chunk\n const existingIdx = chunks.findIndex(\n (c) => c.type === \"thinking\" && c.isMultiAgent\n );\n if (existingIdx >= 0) {\n chunks[existingIdx] = {\n ...chunks[existingIdx],\n content: (chunks[existingIdx].content || \"\") + parsed.reasoning_delta,\n };\n } else {\n chunks.push({\n type: \"thinking\",\n content: parsed.reasoning_delta,\n isMultiAgent: true,\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_multi_agent_planning_complete) {\n // Update existing multi_agent_planning chunk with subagent allocations\n const planningIdx = chunks.findIndex(\n (c) => c.type === \"multi_agent_planning\" && c.isMultiAgent\n );\n if (planningIdx >= 0) {\n chunks[planningIdx] = {\n ...chunks[planningIdx],\n subagentAllocations: parsed.subagents || [],\n };\n } else {\n chunks.push({\n type: \"multi_agent_planning\",\n content: \"\",\n isMultiAgent: true,\n subagentAllocations: parsed.subagents || [],\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_multi_agent_execution_start) {\n // No UI update needed — subagent_start events follow\n continue;\n }\n\n if (parsed.is_subagent_start) {\n chunks.push({\n type: \"subagent_start\",\n content: \"\",\n isMultiAgent: true,\n subagentInfo: {\n id: parsed.subagent_id,\n name: parsed.subagent_name,\n task: parsed.task,\n status: \"running\",\n },\n } as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_subagent_progress) {\n // Update existing subagent chunk with progress\n const subagentIndex = chunks.findIndex(\n (c) =>\n c.type === \"subagent_start\" &&\n c.subagentInfo?.id === parsed.subagent_id\n );\n if (subagentIndex !== -1 && chunks[subagentIndex].subagentInfo) {\n chunks[subagentIndex] = {\n ...chunks[subagentIndex],\n content: parsed.progress || \"\",\n };\n }\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_subagent_complete) {\n chunks.push({\n type: \"subagent_complete\",\n content: \"\",\n isMultiAgent: true,\n subagentInfo: {\n id: parsed.subagent_id,\n name: parsed.subagent_name,\n status: \"completed\",\n result: parsed.result,\n executionTime: parsed.execution_time,\n },\n } as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n if (parsed.is_subagent_failed) {\n chunks.push({\n type: \"subagent_failed\",\n content: \"\",\n isMultiAgent: true,\n subagentInfo: {\n id: parsed.subagent_id,\n name: parsed.subagent_name,\n status: \"failed\",\n error: parsed.error,\n },\n } as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n // Multi-agent synthesis (standalone) — creates synthesis chunk\n if (parsed.is_synthesis_start && isMultiAgentMode) {\n chunks.push({\n type: \"synthesis\",\n content: \"\",\n isMultiAgent: true,\n isSynthesis: true,\n } as AccumulatedChunk);\n updateStreamingMessage();\n continue;\n }\n\n // Extract plan_data metadata when present\n if (parsed.plan_data) {\n const backendPlan = parsed.plan_data;\n currentPlanData = {\n goal: backendPlan.goal || \"\",\n reasoning: backendPlan.reasoning || \"\",\n subtasks: (backendPlan.subtasks || []).map((st: any) => ({\n id: Number(st.id),\n description: st.description,\n required_tools: st.required_tools,\n dependencies: st.dependencies,\n status: \"pending\" as const,\n })),\n total_subtasks: backendPlan.subtasks?.length || 0,\n completed_subtasks: 0,\n failed_subtasks: 0,\n progress_percentage: 0,\n };\n }\n\n // Extract subtask_data metadata when present\n if (parsed.subtask_data) {\n currentSubtaskData = parsed.subtask_data;\n }\n\n // Track synthesis and replan flags\n if (parsed.is_synthesis_start) {\n currentIsSynthesis = true;\n }\n if (parsed.is_replan) {\n currentIsReplan = true;\n }\n\n // Track missing data fields (Gap C)\n if (parsed.tool_args) currentToolArgs = parsed.tool_args;\n if (parsed.replan_attempt !== undefined) currentReplanAttempt = parsed.replan_attempt;\n if (parsed.max_replans !== undefined) currentMaxReplans = parsed.max_replans;\n if (parsed.failure_reason) currentFailureReason = parsed.failure_reason;\n if (parsed.progress) currentProgress = parsed.progress;\n\n // Determine chunk type\n let newChunkType: ChunkType = \"answer\";\n if (parsed.is_thinking) {\n newChunkType = \"thinking\";\n } else if (\n parsed.is_planning ||\n parsed.is_plan_complete ||\n parsed.is_replanning\n ) {\n newChunkType = \"planning\";\n } else if (\n parsed.is_subtask_start ||\n parsed.is_subtask_complete ||\n parsed.is_subtask_failed\n ) {\n newChunkType = \"subtask\";\n } else if (parsed.is_progress_update) {\n newChunkType = \"progress\";\n }\n\n if (newChunkType !== currentChunkType) {\n finalizeChunk();\n currentChunkType = newChunkType;\n }\n\n if (parsed.tool_name) currentToolName = parsed.tool_name;\n if (parsed.success !== undefined) currentSuccess = parsed.success;\n if (parsed.subtask_id !== undefined)\n currentSubtaskId = parsed.subtask_id;\n\n // Accumulate content\n if (newChunkType === \"thinking\") {\n currentChunkContent += parsed.chunk || \"\";\n const match = currentChunkContent.match(\n /\"thought\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/\n );\n if (match) {\n currentChunkContent = match[1]\n .replace(/\\\\n/g, \"\\n\")\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\t/g, \"\\t\")\n .replace(/\\\\\\\\/g, \"\\\\\");\n }\n } else if (newChunkType === \"answer\") {\n const chunkTrimmed = parsed.chunk?.trim() || \"\";\n const accumulatedTrimmed = assistantContent.trim();\n if (\n !(\n chunkTrimmed &&\n accumulatedTrimmed &&\n chunkTrimmed === accumulatedTrimmed\n )\n ) {\n assistantContent += parsed.chunk || \"\";\n }\n } else {\n currentChunkContent += parsed.chunk || \"\";\n }\n\n // Update user message ID\n if (parsed.previous_message_id) {\n callbacks.onUserMessageIdUpdate(\n optimisticId,\n parsed.previous_message_id\n );\n }\n\n updateStreamingMessage();\n }\n // ============================================\n // Claude SDK Native Event Handlers (Gap B)\n // ============================================\n else if (parsed.type === \"claude_text\") {\n // Claude SDK text chunk — accumulate into assistant content\n assistantContent += parsed.chunk || \"\";\n\n const existingTextChunk = chunks.find(\n (c) => c.type === \"claude_text\"\n );\n if (existingTextChunk) {\n existingTextChunk.content += parsed.chunk || \"\";\n } else {\n chunks.push({\n type: \"claude_text\",\n content: parsed.chunk || \"\",\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_thinking\") {\n // Claude SDK extended thinking\n chunks.push({\n type: \"claude_thinking\",\n content: parsed.content || \"\",\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n updateStreamingMessage();\n } else if (parsed.type === \"claude_file_read\") {\n const fileOpData: FileOperationChunkData = {\n toolUseId: parsed.tool_use_id,\n operation: \"read\",\n filePath: parsed.file_path,\n status: parsed.status,\n content: parsed.content,\n totalLines: parsed.total_lines,\n language: parsed.language,\n error: parsed.error,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) =>\n c.type === \"file_operation\" &&\n c.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].fileOperationData = fileOpData;\n } else {\n chunks.push({\n type: \"file_operation\",\n content: \"\",\n toolUseId: parsed.tool_use_id,\n fileOperationData: fileOpData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_file_edit\") {\n const fileEditData: FileOperationChunkData = {\n toolUseId: parsed.tool_use_id,\n operation: \"edit\",\n filePath: parsed.file_path,\n status: parsed.status,\n oldString: parsed.old_string,\n newString: parsed.new_string,\n error: parsed.error,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) =>\n c.type === \"file_operation\" &&\n c.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].fileOperationData = fileEditData;\n } else {\n chunks.push({\n type: \"file_operation\",\n content: \"\",\n toolUseId: parsed.tool_use_id,\n fileOperationData: fileEditData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_file_write\") {\n const fileWriteData: FileOperationChunkData = {\n toolUseId: parsed.tool_use_id,\n operation: \"write\",\n filePath: parsed.file_path,\n status: parsed.status,\n error: parsed.error,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) =>\n c.type === \"file_operation\" &&\n c.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].fileOperationData = fileWriteData;\n } else {\n chunks.push({\n type: \"file_operation\",\n content: \"\",\n toolUseId: parsed.tool_use_id,\n fileOperationData: fileWriteData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_bash\") {\n const termData: TerminalChunkData = {\n toolUseId: parsed.tool_use_id,\n command: parsed.command,\n description: parsed.description,\n status: parsed.status,\n stdout: parsed.stdout,\n stderr: parsed.stderr,\n exitCode: parsed.exit_code,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) =>\n c.type === \"terminal\" && c.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].terminalData = termData;\n } else {\n chunks.push({\n type: \"terminal\",\n content: \"\",\n toolUseId: parsed.tool_use_id,\n terminalData: termData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_search\") {\n const searchData: SearchResultsChunkData = {\n toolUseId: parsed.tool_use_id,\n tool: parsed.tool,\n pattern: parsed.pattern,\n path: parsed.path,\n status: parsed.status,\n results: (parsed.results || []).map((r: any) => ({\n filePath: r.file_path,\n lineNumber: r.line_number,\n snippet: r.snippet,\n })),\n totalCount: parsed.total_count || 0,\n error: parsed.error,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) =>\n c.type === \"search_results\" &&\n c.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].searchResultsData = searchData;\n } else {\n chunks.push({\n type: \"search_results\",\n content: \"\",\n toolUseId: parsed.tool_use_id,\n searchResultsData: searchData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (\n parsed.type === \"claude_web_search\" ||\n parsed.type === \"claude_web_fetch\"\n ) {\n const webOpData: WebOperationChunkData = {\n toolUseId: parsed.tool_use_id,\n operation:\n parsed.type === \"claude_web_search\" ? \"search\" : \"fetch\",\n query: parsed.query,\n url: parsed.url,\n status: parsed.status,\n results: parsed.results,\n content: parsed.content,\n error: parsed.error,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) =>\n c.type === \"web_operation\" &&\n c.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].webOperationData = webOpData;\n } else {\n chunks.push({\n type: \"web_operation\",\n content: \"\",\n toolUseId: parsed.tool_use_id,\n webOperationData: webOpData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_subagent_start\") {\n const subData: SubagentChunkData = {\n subagentId: parsed.subagent_id,\n subagentType: parsed.subagent_type,\n description: parsed.description,\n prompt: parsed.prompt,\n status: \"running\",\n nestedChunks: [],\n };\n chunks.push({\n type: \"subagent\",\n content: \"\",\n toolUseId: parsed.parent_tool_use_id,\n subagentData: subData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n updateStreamingMessage();\n } else if (parsed.type === \"claude_subagent_chunk\") {\n // Append to existing subagent's nested chunks\n const subagentIdx = chunks.findIndex(\n (c) =>\n c.type === \"subagent\" &&\n c.subagentData?.subagentId === parsed.subagent_id\n );\n if (subagentIdx >= 0 && chunks[subagentIdx].subagentData) {\n chunks[subagentIdx].subagentData!.nestedChunks.push({\n type: parsed.is_tool ? \"tool\" : \"answer\",\n content: parsed.chunk || \"\",\n toolName: parsed.tool_name,\n orchestrator: \"claude_agent_sdk\",\n } as unknown as StreamingChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"claude_subagent_complete\") {\n // Update existing subagent chunk with completion info\n const subagentIdx = chunks.findIndex(\n (c) =>\n c.type === \"subagent\" &&\n c.subagentData?.subagentId === parsed.subagent_id\n );\n if (subagentIdx >= 0 && chunks[subagentIdx].subagentData) {\n chunks[subagentIdx].subagentData!.status = \"completed\";\n chunks[subagentIdx].subagentData!.result = parsed.result;\n chunks[subagentIdx].subagentData!.durationMs =\n parsed.duration_ms;\n }\n updateStreamingMessage();\n } else if (\n parsed.type === \"claude_tool_use\" ||\n parsed.type === \"claude_tool_result\"\n ) {\n // Generic Claude tool (MCP tools, etc.)\n const claudeToolData: ClaudeToolChunkData = {\n toolUseId: parsed.tool_use_id,\n toolName: parsed.tool_name,\n toolDescription: parsed.tool_description,\n toolInput: parsed.tool_input,\n status:\n parsed.type === \"claude_tool_use\"\n ? \"pending\"\n : parsed.is_error\n ? \"error\"\n : \"completed\",\n content: parsed.content,\n isError: parsed.is_error,\n durationMs: parsed.duration_ms,\n };\n const existingIdx = chunks.findIndex(\n (c) => c.claudeToolData?.toolUseId === parsed.tool_use_id\n );\n if (existingIdx >= 0) {\n chunks[existingIdx].claudeToolData = claudeToolData;\n } else {\n chunks.push({\n type: \"tool\",\n content: parsed.content || \"\",\n toolUseId: parsed.tool_use_id,\n toolName: parsed.tool_name,\n toolDescription: parsed.tool_description,\n status:\n claudeToolData.status === \"pending\" ? \"planned\" : \"completed\",\n claudeToolData,\n orchestrator: \"claude_agent_sdk\",\n } as AccumulatedChunk);\n }\n updateStreamingMessage();\n } else if (parsed.type === \"clarification_needed\") {\n // Agent is requesting user clarification\n finalizeChunk();\n\n const clarificationData: ClarificationData = {\n question: parsed.question || \"\",\n options: parsed.options || [],\n context: parsed.context,\n allowFreeText: parsed.allow_free_text !== false,\n subtaskId: parsed.subtask_id,\n subtaskDescription: parsed.subtask_description,\n subagentName: parsed.subagent_name,\n subagentRole: parsed.subagent_role,\n };\n\n // Add clarification chunk\n chunks.push({\n type: \"clarification_needed\",\n content: clarificationData.question,\n clarificationData,\n subtaskId: parsed.subtask_id,\n });\n\n pendingClarification = clarificationData;\n\n // Set as message body so user sees the question\n if (!assistantContent) {\n assistantContent = clarificationData.question;\n }\n\n updateStreamingMessage();\n } else if (parsed.type === \"assistant_complete\") {\n finalizeChunk();\n receivedComplete = true;\n\n const finalContent =\n parsed.message?.text_content || assistantContent;\n const finalId = parsed.message?.id;\n const sources = parsed.message?.metadata?.sources;\n\n const elapsedSeconds = (Date.now() - streamStartTime) / 1000;\n callbacks.onComplete(\n assistantMsgId,\n finalContent,\n finalId,\n chunks as unknown as StreamingChunk[],\n suggestedActions,\n sources,\n pendingClarification,\n elapsedSeconds\n );\n assistantContent = finalContent;\n if (finalId) assistantMsgId = finalId;\n break;\n } else if (\n parsed.type === \"client_tool_invocation\" &&\n parsed.invocation &&\n callbacks.onToolInvocation\n ) {\n // Execute async — don't block the stream\n callbacks.onToolInvocation(parsed.invocation);\n } else if (parsed.type === \"error\") {\n throw new Error(parsed.error || \"Stream error\");\n } else if (parsed.type === \"done\") {\n // Fallback: if stream ended without assistant_complete (e.g. clarification early return),\n // finalize the message so the frontend still shows it properly\n if (assistantMsgId && !receivedComplete) {\n finalizeChunk();\n const elapsedSecondsDone = (Date.now() - streamStartTime) / 1000;\n callbacks.onComplete(\n assistantMsgId,\n assistantContent || \"\",\n parsed.message_id,\n chunks as unknown as StreamingChunk[],\n suggestedActions,\n undefined,\n pendingClarification,\n elapsedSecondsDone\n );\n } else if (parsed.message_id && assistantMsgId) {\n callbacks.onMessageUpdate({\n id: assistantMsgId,\n isStreaming: false,\n });\n }\n if (parsed.message_id) assistantMsgId = parsed.message_id;\n break;\n }\n } catch (e) {\n // If it's a real error (not JSON parse), re-throw\n if (e instanceof Error && e.message !== \"Stream error\") {\n // Check if this is a thrown stream error vs JSON parse error\n if (\n e.message.startsWith(\"Stream error\") ||\n e.message.startsWith(\"HTTP error\")\n ) {\n throw e;\n }\n }\n // Skip invalid JSON lines\n }\n }\n }\n\n return { assistantMsgId, assistantContent };\n}\n\n// ============================================================================\n// Main Hook\n// ============================================================================\n\nexport function useMiiflowChat(config: MiiflowChatConfig): MiiflowChatResult {\n const [messages, setMessages] = useState<InternalMessage[]>([]);\n const [isStreaming, setIsStreaming] = useState(false);\n const [streamingMessageId, setStreamingMessageId] = useState<string | null>(\n null\n );\n const [session, setSession] = useState<EmbedSession | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const configRef = useRef(config);\n configRef.current = config;\n\n // Refs for mutable state — allows stable callback references\n // that always read the latest values (fixes stale closure in widget bridge)\n const sessionRef = useRef(session);\n sessionRef.current = session;\n const isStreamingRef = useRef(isStreaming);\n isStreamingRef.current = isStreaming;\n\n const toolHandlersRef = useRef(new Map<string, ToolHandler>());\n const toolDefinitionsRef = useRef(\n new Map<string, Omit<ClientToolDefinition, \"handler\">>()\n );\n\n\n // Initialize session on mount\n useEffect(() => {\n let cancelled = false;\n\n async function init() {\n try {\n const sess = await initSession(configRef.current);\n if (!cancelled) {\n setSession(sess);\n setLoading(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(\n err instanceof Error ? err.message : \"Failed to initialize\"\n );\n setLoading(false);\n }\n }\n }\n\n init();\n return () => {\n cancelled = true;\n };\n }, [config.publicKey, config.assistantId]);\n\n // Derive branding\n const branding = useMemo(() => mapSessionBranding(session), [session]);\n const brandingCSSVars = useBrandingCSSVars(branding);\n\n // Upload file — store metadata for attaching to user messages\n const uploadedAttachmentsRef = useRef(new Map<string, import(\"../types\").Attachment>());\n\n // Upload file — uses sessionRef for stable reference\n const uploadFile = useCallback(\n async (file: File): Promise<string> => {\n const currentSession = sessionRef.current;\n if (!currentSession) throw new Error(\"Not initialized\");\n const attachmentId = await uploadFileToBackend(configRef.current, currentSession, file);\n uploadedAttachmentsRef.current.set(attachmentId, {\n id: attachmentId,\n filename: file.name,\n mimeType: file.type,\n size: file.size,\n isImage: file.type.startsWith(\"image/\"),\n isVideo: file.type.startsWith(\"video/\"),\n isDocument: !file.type.startsWith(\"image/\") && !file.type.startsWith(\"video/\"),\n });\n return attachmentId;\n },\n [], // stable — reads sessionRef\n );\n\n // Remove uploaded attachment metadata (called when user removes attachment before sending)\n const removeUploadedAttachment = useCallback((attachmentId: string) => {\n uploadedAttachmentsRef.current.delete(attachmentId);\n }, []);\n\n // Handle tool invocation from backend. Returns true if handled locally.\n // Uses sessionRef for stable reference — safe to capture in widget bridge.\n const handleToolInvocation = useCallback(\n async (invocation: ToolInvocationRequest): Promise<boolean> => {\n const currentSession = sessionRef.current;\n if (!currentSession) throw new Error(\"Not initialized\");\n\n const { invocation_id, tool_name, parameters } = invocation;\n console.log(`[Miiflow] Tool invocation received: \"${tool_name}\" (id: ${invocation_id})`);\n const handler = toolHandlersRef.current.get(tool_name);\n\n if (!handler) {\n // No local handler — let caller try fallback / sibling widgets\n return false;\n }\n\n try {\n const result = await Promise.race([\n handler(parameters),\n new Promise((_, reject) =>\n setTimeout(\n () => reject(new Error(\"Tool execution timeout (30s)\")),\n 30000\n )\n ),\n ]);\n\n console.log(`[Miiflow] Tool \"${tool_name}\" executed successfully (id: ${invocation_id})`);\n await sendToolResult(configRef.current, currentSession, {\n invocation_id,\n result,\n });\n console.log(`[Miiflow] Tool result sent for \"${tool_name}\" (id: ${invocation_id})`);\n return true;\n } catch (error) {\n console.error(\n `[Miiflow] Tool '${tool_name}' execution failed:`,\n error\n );\n await sendToolResult(configRef.current, currentSession, {\n invocation_id,\n error: error instanceof Error ? error.message : String(error),\n });\n return true; // Handler existed but threw — still \"handled\"\n }\n },\n [] // stable — reads sessionRef\n );\n\n // WebSocket connection for client tool invocations\n useEffect(() => {\n if (!session) return;\n\n const currentSession = session; // capture non-null for closure\n\n let ws: WebSocket | null = null;\n let heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let reconnectAttempt = 0;\n let disposed = false;\n\n function connect() {\n if (disposed) return;\n\n const url = buildWebSocketUrl(configRef.current, currentSession);\n ws = new WebSocket(url);\n\n ws.onopen = () => {\n console.log(\"[Miiflow] WebSocket connected\");\n reconnectAttempt = 0;\n\n // Start heartbeat\n heartbeatTimer = setInterval(() => {\n if (ws?.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"heartbeat\" }));\n }\n }, WS_HEARTBEAT_INTERVAL);\n };\n\n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n if (data.type === \"client_tool_invocation\" && data.invocation) {\n handleToolInvocation(data.invocation).then(async (handled) => {\n if (!handled) {\n const fallback = configRef.current.onToolInvocationFallback;\n const fallbackHandled = fallback ? await fallback(data.invocation) : false;\n if (!fallbackHandled) {\n // Send error back to backend so it doesn't hang waiting for result\n sendToolResult(configRef.current, currentSession, {\n invocation_id: data.invocation.invocation_id,\n error: `No handler found for tool '${data.invocation.tool_name}'`,\n }).catch(console.error);\n }\n }\n }).catch(console.error);\n }\n } catch {\n // Ignore malformed messages\n }\n };\n\n ws.onclose = () => {\n if (heartbeatTimer) {\n clearInterval(heartbeatTimer);\n heartbeatTimer = null;\n }\n\n if (!disposed) {\n const delay = Math.min(\n WS_RECONNECT_BASE_DELAY * Math.pow(2, reconnectAttempt),\n WS_RECONNECT_MAX_DELAY,\n );\n reconnectAttempt++;\n console.log(`[Miiflow] WebSocket closed, reconnecting in ${delay}ms`);\n reconnectTimer = setTimeout(connect, delay);\n }\n };\n\n ws.onerror = (err) => {\n console.error(\"[Miiflow] WebSocket error:\", err);\n };\n }\n\n connect();\n\n return () => {\n disposed = true;\n if (heartbeatTimer) clearInterval(heartbeatTimer);\n if (reconnectTimer) clearTimeout(reconnectTimer);\n if (ws) {\n ws.onclose = null; // Prevent reconnect on intentional close\n ws.close();\n }\n };\n }, [session, handleToolInvocation]);\n\n // Send system event — uses sessionRef for stable reference\n const sendSystemEvent = useCallback(\n async (event: SystemEvent): Promise<void> => {\n const currentSession = sessionRef.current;\n if (!currentSession) throw new Error(\"Not initialized\");\n await sendSystemEventToBackend(configRef.current, currentSession, event);\n },\n [] // stable — reads sessionRef\n );\n\n // Send message — uses refs for stable reference, safe to capture in widget bridge.\n // Also fixes: allows attachment-only messages (empty text with attachmentIds).\n const sendMessage = useCallback(\n async (content: string, attachmentIds?: string[]) => {\n const currentSession = sessionRef.current;\n const hasText = !!content.trim();\n const hasAttachments = attachmentIds && attachmentIds.length > 0;\n\n if ((!hasText && !hasAttachments) || isStreamingRef.current || !currentSession) return;\n\n const optimisticId = `msg-${Date.now()}`;\n\n const messageAttachments = attachmentIds\n ?.map((id) => uploadedAttachmentsRef.current.get(id))\n .filter(Boolean) as import(\"../types\").Attachment[] | undefined;\n\n const userMessage: InternalMessage = {\n id: optimisticId,\n textContent: content,\n participant: {\n id: \"user\",\n name: configRef.current.userName || \"You\",\n role: \"user\",\n },\n createdAt: new Date().toISOString(),\n attachments: messageAttachments?.length ? messageAttachments : undefined,\n };\n\n // Clean up stored attachment metadata\n attachmentIds?.forEach((id) => uploadedAttachmentsRef.current.delete(id));\n\n // Add placeholder assistant message to show loading dots immediately\n const placeholderAssistantId = `assistant-pending-${Date.now()}`;\n const placeholderAssistant: InternalMessage = {\n id: placeholderAssistantId,\n textContent: \"\",\n participant: {\n id: \"assistant\",\n name:\n currentSession.config.branding?.custom_name ||\n currentSession.config.assistant_name,\n role: \"assistant\",\n avatarUrl: currentSession.config.branding?.assistant_avatar,\n },\n createdAt: new Date().toISOString(),\n isStreaming: true,\n };\n\n setMessages((prev) => [...prev, userMessage, placeholderAssistant]);\n setIsStreaming(true);\n setStreamingMessageId(placeholderAssistantId);\n\n // Notify consumer that a user message was created (for widget event emission)\n configRef.current.onUserMessageCreated?.({ id: optimisticId, content });\n\n try {\n const backendBaseUrl = getBackendBaseUrl(configRef.current);\n\n const response = await fetch(\n `${backendBaseUrl}/assistant/message/stream/`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${currentSession.token}`,\n \"x-mii-user-id\": getOrCreateUserId(),\n },\n body: JSON.stringify({\n thread_id: currentSession.config.thread_id,\n text_content: content,\n message_id: optimisticId,\n metadata: {},\n attachment_ids: attachmentIds || [],\n }),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const result = await parseSSEStream(\n reader,\n currentSession,\n optimisticId,\n {\n onMessageCreate: (msg) => {\n setStreamingMessageId(msg.id);\n // Replace placeholder with real streaming message\n setMessages((prev) => {\n const filtered = prev.filter(\n (m) => m.id !== placeholderAssistantId\n );\n return [...filtered, msg];\n });\n },\n onMessageUpdate: (update) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === update.id ? { ...msg, ...update } : msg\n )\n );\n },\n onUserMessageIdUpdate: (oldId, newId) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === oldId ? { ...msg, id: newId } : msg\n )\n );\n },\n onComplete: (\n assistantMsgId,\n finalContent,\n finalId,\n chunks,\n suggestedActions,\n sources,\n pendingClarification,\n executionTime\n ) => {\n if (assistantMsgId) {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMsgId\n ? {\n ...msg,\n id: finalId || msg.id,\n textContent: finalContent,\n isStreaming: false,\n reasoning: chunks,\n suggestedActions,\n citations: sources,\n pendingClarification,\n executionTime,\n }\n : msg\n )\n );\n }\n\n // Notify consumer that assistant message is complete (for widget event emission)\n configRef.current.onAssistantMessageComplete?.({\n id: finalId || assistantMsgId || \"\",\n content: finalContent,\n });\n },\n onToolInvocation: async (invocation) => {\n const handled = await handleToolInvocation(invocation);\n if (!handled) {\n const fallback = configRef.current.onToolInvocationFallback;\n const fallbackHandled = fallback ? await fallback(invocation) : false;\n if (!fallbackHandled) {\n const sess = sessionRef.current;\n if (sess) {\n await sendToolResult(configRef.current, sess, {\n invocation_id: invocation.invocation_id,\n error: `No handler found for tool '${invocation.tool_name}'`,\n });\n }\n }\n }\n },\n }\n );\n\n // Ensure streaming is marked complete\n if (result.assistantMsgId) {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === result.assistantMsgId\n ? { ...msg, isStreaming: false }\n : msg\n )\n );\n }\n } catch (err) {\n console.error(\"[Miiflow] Send error:\", err);\n\n const sess = sessionRef.current;\n const errorMsg: InternalMessage = {\n id: `error-${Date.now()}`,\n textContent: \"Sorry, I encountered an error. Please try again.\",\n participant: {\n id: \"assistant\",\n name:\n sess?.config.branding?.custom_name ||\n sess?.config.assistant_name || \"Assistant\",\n role: \"assistant\",\n avatarUrl: sess?.config.branding?.assistant_avatar,\n },\n createdAt: new Date().toISOString(),\n };\n // Remove placeholder and add error message\n setMessages((prev) => [\n ...prev.filter((m) => m.id !== placeholderAssistantId),\n errorMsg,\n ]);\n setError(err instanceof Error ? err.message : \"Send failed\");\n } finally {\n setIsStreaming(false);\n setStreamingMessageId(null);\n }\n },\n [handleToolInvocation] // stable — reads sessionRef and isStreamingRef\n );\n\n // Start new thread — uses sessionRef for stable reference\n const startNewThread = useCallback(async (): Promise<string> => {\n const currentSession = sessionRef.current;\n if (!currentSession) throw new Error(\"Not initialized\");\n\n const result = await createThread(configRef.current, currentSession);\n if (!result.token) {\n console.warn(\"[Miiflow] CreateThread did not return new token — tools may register to wrong thread\");\n }\n const updatedSession: EmbedSession = {\n ...currentSession,\n config: { ...currentSession.config, thread_id: result.threadId },\n token: result.token || currentSession.token,\n };\n // Update ref synchronously so that any calls made immediately after\n // startNewThread (e.g. registerTools) use the new session/token.\n // setSession alone is async (React batches state updates) and won't\n // update sessionRef until the next render, causing a race condition\n // where tools get registered on the OLD thread.\n sessionRef.current = updatedSession;\n setSession(updatedSession);\n setMessages([]);\n\n // Re-register tools on new thread\n if (toolDefinitionsRef.current.size > 0) {\n console.log(`[Miiflow] Re-registering ${toolDefinitionsRef.current.size} tools on new thread`);\n try {\n await registerToolsOnBackend(\n configRef.current,\n updatedSession,\n Array.from(toolDefinitionsRef.current.values())\n );\n } catch (err) {\n console.warn(\"[Miiflow] Failed to re-register tools:\", err);\n }\n }\n\n return result.threadId;\n }, []); // stable — reads sessionRef\n\n // Register tool — uses sessionRef for stable reference\n const registerTool = useCallback(\n async (tool: ClientToolDefinition): Promise<void> => {\n const currentSession = sessionRef.current;\n if (!currentSession) throw new Error(\"Not initialized\");\n\n validateToolDefinition(tool);\n\n toolHandlersRef.current.set(tool.name, tool.handler);\n const serialized = serializeToolDefinition(tool);\n toolDefinitionsRef.current.set(tool.name, serialized);\n\n try {\n await registerToolsOnBackend(configRef.current, currentSession, [serialized]);\n console.log(`[Miiflow] Tool registered: \"${tool.name}\"`);\n } catch (err) {\n toolHandlersRef.current.delete(tool.name);\n toolDefinitionsRef.current.delete(tool.name);\n throw err;\n }\n },\n [] // stable — reads sessionRef\n );\n\n // Register multiple tools — sends all definitions in a single batch request\n // (matching old MUI implementation behavior). Falls back to one-by-one if\n // only one tool is provided.\n const registerTools = useCallback(\n async (tools: ClientToolDefinition[]): Promise<void> => {\n const currentSession = sessionRef.current;\n if (!currentSession) throw new Error(\"Not initialized\");\n\n // Validate all tools first before making any changes\n for (const tool of tools) {\n validateToolDefinition(tool);\n }\n\n // Store handlers and definitions locally\n const previousHandlers = new Map(toolHandlersRef.current);\n const previousDefinitions = new Map(toolDefinitionsRef.current);\n\n const serializedTools: Array<Omit<ClientToolDefinition, \"handler\">> = [];\n for (const tool of tools) {\n toolHandlersRef.current.set(tool.name, tool.handler);\n const serialized = serializeToolDefinition(tool);\n toolDefinitionsRef.current.set(tool.name, serialized);\n serializedTools.push(serialized);\n }\n\n try {\n // Send all tool definitions in one batch request\n await registerToolsOnBackend(configRef.current, currentSession, serializedTools);\n const toolNames = tools.map(t => t.name);\n console.log(`[Miiflow] Tools registered: ${JSON.stringify(toolNames)} (${tools.length} tools)`);\n } catch (err) {\n // Rollback all handlers and definitions on failure\n toolHandlersRef.current = previousHandlers;\n toolDefinitionsRef.current = previousDefinitions;\n throw err;\n }\n },\n [] // stable — reads sessionRef\n );\n\n // Convert internal messages to ChatMessage format\n const chatMessages: ChatMessage[] = useMemo(\n () =>\n messages.map((msg) => ({\n id: msg.id,\n textContent: msg.textContent?.replace(/\\[ref:[^\\]]+\\]/g, '') || msg.textContent,\n participant: msg.participant,\n createdAt: msg.createdAt,\n isStreaming: msg.isStreaming,\n reasoning: msg.reasoning,\n suggestedActions: msg.suggestedActions,\n citations: msg.citations,\n attachments: msg.attachments,\n pendingClarification: msg.pendingClarification,\n executionTime: msg.executionTime,\n })),\n [messages]\n );\n\n // Allow external session updates (e.g. token refresh from widget class)\n const updateSession = useCallback((newSession: EmbedSession) => {\n setSession(newSession);\n }, []);\n\n return {\n messages: chatMessages,\n isStreaming,\n streamingMessageId,\n sendMessage,\n uploadFile,\n removeUploadedAttachment,\n session,\n loading,\n error,\n branding,\n brandingCSSVars,\n startNewThread,\n registerTool,\n registerTools,\n sendSystemEvent,\n handleToolInvocation,\n updateSession,\n };\n}\n","/**\n * Utility functions for parsing and managing JWT tokens.\n * Used for proactive token refresh before expiration.\n */\n\n/**\n * Parse the expiry time from a JWT token.\n * Returns the expiry timestamp in milliseconds, or null if parsing fails.\n */\nexport function parseTokenExpiry(token: string): number | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const base64 = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const jsonPayload = atob(base64);\n const decoded = JSON.parse(jsonPayload);\n\n if (typeof decoded.exp === \"number\") {\n return decoded.exp * 1000;\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a token is expiring soon (within the given threshold).\n */\nexport function isTokenExpiringSoon(\n token: string,\n thresholdMs: number\n): boolean {\n const expiry = parseTokenExpiry(token);\n if (expiry === null) return true;\n return expiry - Date.now() <= thresholdMs;\n}\n\n/**\n * Check if a token has already expired.\n */\nexport function isTokenExpired(token: string): boolean {\n const expiry = parseTokenExpiry(token);\n if (expiry === null) return true;\n return Date.now() >= expiry;\n}\n\n/**\n * Get the time remaining until token expiry in milliseconds.\n */\nexport function getTimeUntilExpiry(token: string): number {\n const expiry = parseTokenExpiry(token);\n if (expiry === null) return 0;\n return Math.max(0, expiry - Date.now());\n}\n"]}
|