@miiflow/assistant-ui 0.3.2 → 0.3.3

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.
@@ -1 +1 @@
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":"uGASO,SAASA,CAAAA,CAAkBC,CAAAA,CAAmC,CACpE,OAAIA,CAAAA,CAAO,OAAA,CAAgBA,CAAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,WAAA,CAAa,EAAE,CAAA,CAGhEA,CAAAA,CAAO,SAAA,EAAW,QAAA,CAAS,WAAW,CAAA,EACtCA,CAAAA,CAAO,SAAA,EAAW,QAAA,CAAS,WAAW,CAAA,EACtC,KAAA,CACc,uBAAA,CAA0B,wBAC1C,CAKO,SAASC,CAAAA,EAA4B,CAC3C,IAAMC,CAAAA,CAAM,iBAAA,CACRC,CAAAA,CAAwB,IAAA,CAC5B,GAAI,CACHA,CAAAA,CAAS,YAAA,CAAa,OAAA,CAAQD,CAAG,EAClC,CAAA,KAAQ,CAER,CACA,GAAI,CAACC,CAAAA,CAAQ,CACZA,CAAAA,CAAS,QAAQ,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,CAC9E,GAAI,CACH,YAAA,CAAa,OAAA,CAAQD,CAAAA,CAAKC,CAAM,EACjC,CAAA,KAAQ,CAER,CACD,CACA,OAAOA,CACR,CAKA,eAAsBC,EAAAA,CAAYJ,CAAAA,CAAkD,CACnF,IAAMK,CAAAA,CAAiBN,CAAAA,CAAkBC,CAAM,CAAA,CAEzCM,CAAAA,CAAW,MAAM,KAAA,CAAM,CAAA,EAAGD,CAAc,CAAA,eAAA,CAAA,CAAmB,CAChE,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACR,cAAA,CAAgB,kBAAA,CAChB,oBAAA,CAAsBL,CAAAA,CAAO,SAAA,CAC7B,eAAA,CAAiBC,CAAAA,EAClB,CAAA,CACA,IAAA,CAAM,IAAA,CAAK,UAAU,CACpB,YAAA,CAAcD,CAAAA,CAAO,WAAA,CACrB,SAAA,CAAW,CACV,OAAA,CAASA,CAAAA,CAAO,MAAA,CAChB,IAAA,CAAMA,CAAAA,CAAO,QAAA,CACb,KAAA,CAAOA,CAAAA,CAAO,SACf,CACD,CAAC,CACF,CAAC,CAAA,CAED,GAAI,CAACM,CAAAA,CAAS,EAAA,CAAI,CACjB,IAAMC,CAAAA,CAAY,MAAMD,CAAAA,CAAS,IAAA,EAAK,CACtC,MAAM,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgBA,CAAAA,CAAS,MAAM,CAAA,GAAA,EAAMC,CAAS,CAAA,CAAE,CACjE,CAEA,IAAMC,CAAAA,CAAO,MAAMF,CAAAA,CAAS,IAAA,EAAK,CACjC,GAAI,CAACE,CAAAA,CAAK,OAAA,CACT,MAAM,IAAI,KAAA,CAAMA,CAAAA,CAAK,KAAA,EAAS,8BAA8B,CAAA,CAG7D,OAAO,CACN,KAAA,CAAOA,CAAAA,CAAK,KAAA,CACZ,MAAA,CAAQA,CAAAA,CAAK,MAAA,CACb,UAAA,CAAYA,CAAAA,CAAK,UAClB,CACD,CAKA,eAAsBC,EAAAA,CACrBT,CAAAA,CACAU,CAAAA,CACgD,CAChD,IAAML,CAAAA,CAAiBN,CAAAA,CAAkBC,CAAM,CAAA,CAEzCM,CAAAA,CAAW,MAAM,KAAA,CAAM,CAAA,EAAGD,CAAc,CAAA,kBAAA,CAAA,CAAsB,CACnE,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACR,cAAA,CAAgB,kBAAA,CAChB,aAAA,CAAe,CAAA,OAAA,EAAUK,CAAAA,CAAQ,KAAK,CAAA,CAAA,CACtC,eAAA,CAAiBT,CAAAA,EAClB,CAAA,CACA,IAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CACpB,aAAA,CAAe,cAAA,CACf,SAAA,CAAW,CACV,KAAA,CAAO,CACN,WAAA,CAAaS,CAAAA,CAAQ,MAAA,CAAO,YAAA,CAC5B,IAAA,CAAM,YAAA,CACN,SAAA,CAAW,KACZ,CACD,CAAA,CACA,KAAA,CAAO,CAAA;AAAA;AAAA;AAAA;AAAA,OAAA,CAKR,CAAC,CACF,CAAC,CAAA,CAED,GAAI,CAACJ,CAAAA,CAAS,EAAA,CACb,MAAM,IAAI,MAAM,CAAA,yBAAA,EAA4BA,CAAAA,CAAS,MAAM,CAAA,CAAE,CAAA,CAG9D,IAAMK,CAAAA,CAAS,MAAML,CAAAA,CAAS,IAAA,GACxBM,CAAAA,CAAcD,CAAAA,CAAO,IAAA,EAAM,YAAA,EAAc,QAAQ,EAAA,CAEvD,GAAI,CAACC,CAAAA,CACJ,MAAM,IAAI,KAAA,CAAM,uBAAuB,CAAA,CAGxC,OAAO,CAAE,QAAA,CAAUA,CAAAA,CAAa,KAAA,CAAOD,CAAAA,CAAO,KAAM,CACrD,CAKA,eAAsBE,EAAAA,CACrBb,EACAU,CAAAA,CACAI,CAAAA,CACgB,CAChB,IAAMT,EAAiBN,CAAAA,CAAkBC,CAAM,EAE/C,MAAM,KAAA,CAAM,GAAGK,CAAc,CAAA,iBAAA,CAAA,CAAqB,CACjD,MAAA,CAAQ,OACR,OAAA,CAAS,CACR,cAAA,CAAgB,kBAAA,CAChB,cAAe,CAAA,OAAA,EAAUK,CAAAA,CAAQ,KAAK,CAAA,CACvC,EACA,IAAA,CAAM,IAAA,CAAK,UAAU,CAAE,SAAA,CAAWI,CAAS,CAAC,CAC7C,CAAC,EACF,CAMA,eAAsBC,EAAAA,CAAWf,CAAAA,CAA2BU,CAAAA,CAAuBM,EAA6B,CAE/G,IAAMC,CAAAA,CAAY,CAAA,EADKlB,EAAkBC,CAAM,CACZ,+BAE7BkB,CAAAA,CAAW,IAAI,SACrBA,CAAAA,CAAS,MAAA,CAAO,MAAA,CAAQF,CAAI,EAE5B,IAAMV,CAAAA,CAAW,MAAM,KAAA,CAAMW,EAAW,CACvC,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACR,aAAA,CAAe,CAAA,OAAA,EAAUP,EAAQ,KAAK,CAAA,CAAA,CACtC,gBAAiBT,CAAAA,EAClB,CAAA,CACA,IAAA,CAAMiB,CACP,CAAC,CAAA,CAED,GAAI,CAACZ,EAAS,EAAA,CAAI,CACjB,IAAMC,CAAAA,CAAY,MAAMD,CAAAA,CAAS,IAAA,GACjC,MAAM,IAAI,MAAM,CAAA,eAAA,EAAkBA,CAAAA,CAAS,MAAM,CAAA,GAAA,EAAMC,CAAS,CAAA,CAAE,CACnE,CAGA,IAAMY,CAAAA,CAAAA,CADO,MAAMb,CAAAA,CAAS,IAAA,EAAK,EACP,UAAA,EAAY,GAEtC,GAAI,CAACa,EACJ,MAAM,IAAI,MAAM,2BAA2B,CAAA,CAG5C,OAAOA,CACR,CAKA,eAAsBC,EAAAA,CACrBpB,CAAAA,CACAU,CAAAA,CACAW,EACgB,CAChB,IAAMhB,CAAAA,CAAiBN,CAAAA,CAAkBC,CAAM,CAAA,CAEzCM,CAAAA,CAAW,MAAM,KAAA,CAAM,CAAA,EAAGD,CAAc,CAAA,uBAAA,CAAA,CAA2B,CACxE,MAAA,CAAQ,MAAA,CACR,QAAS,CACR,cAAA,CAAgB,kBAAA,CAChB,aAAA,CAAe,UAAUK,CAAAA,CAAQ,KAAK,CAAA,CAAA,CACtC,eAAA,CAAiBT,GAClB,CAAA,CACA,KAAM,IAAA,CAAK,SAAA,CAAU,CACpB,SAAA,CAAWS,CAAAA,CAAQ,MAAA,CAAO,SAAA,CAC1B,aAAc,CACb,MAAA,CAAQW,CAAAA,CAAY,MAAA,CACpB,YAAaA,CAAAA,CAAY,WAAA,CACzB,mBAAA,CAAqBA,CAAAA,CAAY,oBACjC,QAAA,CAAUA,CAAAA,CAAY,UAAY,EACnC,CACD,CAAC,CACF,CAAC,CAAA,CAED,GAAI,CAACf,CAAAA,CAAS,GAAI,CACjB,IAAMC,EAAY,MAAMD,CAAAA,CAAS,IAAA,EAAK,CACtC,MAAM,IAAI,KAAA,CAAM,gCAAgCA,CAAAA,CAAS,MAAM,MAAMC,CAAS,CAAA,CAAE,CACjF,CAEA,IAAMI,CAAAA,CAAS,MAAML,CAAAA,CAAS,IAAA,GAC9B,GAAI,CAACK,CAAAA,CAAO,OAAA,CACX,MAAM,IAAI,KAAA,CAAMA,EAAO,KAAA,EAAS,6BAA6B,CAE/D,CAKA,eAAsBW,CAAAA,CACrBtB,CAAAA,CACAU,EACAC,CAAAA,CACgB,CAChB,IAAMN,CAAAA,CAAiBN,EAAkBC,CAAM,CAAA,CAEzCM,CAAAA,CAAW,MAAM,MAAM,CAAA,EAAGD,CAAc,yBAA0B,CACvE,MAAA,CAAQ,OACR,OAAA,CAAS,CACR,cAAA,CAAgB,kBAAA,CAChB,cAAe,CAAA,OAAA,EAAUK,CAAAA,CAAQ,KAAK,CAAA,CACvC,EACA,IAAA,CAAM,IAAA,CAAK,SAAA,CAAUC,CAAM,CAC5B,CAAC,CAAA,CAED,GAAI,CAACL,CAAAA,CAAS,GAAI,CACjB,IAAMC,CAAAA,CAAY,MAAMD,EAAS,IAAA,EAAK,CACtC,MAAM,IAAI,KAAA,CAAM,+BAA+BA,CAAAA,CAAS,MAAM,CAAA,GAAA,EAAMC,CAAS,EAAE,CAChF,CAEA,IAAMgB,CAAAA,CAAe,MAAMjB,EAAS,IAAA,EAAK,CACzC,GAAI,CAACiB,EAAa,OAAA,CACjB,MAAM,IAAI,KAAA,CAAM,+BAA+BA,CAAAA,CAAa,KAAK,CAAA,CAAE,CAErE,CAKA,eAAsBC,CAAAA,CACrBxB,EACAU,CAAAA,CACAe,CAAAA,CACgB,CAChB,IAAMpB,CAAAA,CAAiBN,CAAAA,CAAkBC,CAAM,EAE/C,GAAIyB,CAAAA,CAAgB,MAAA,GAAW,CAAA,CAAG,CACjC,IAAMnB,CAAAA,CAAW,MAAM,KAAA,CAAM,GAAGD,CAAc,CAAA,wBAAA,CAAA,CAA4B,CACzE,MAAA,CAAQ,MAAA,CACR,QAAS,CACR,cAAA,CAAgB,kBAAA,CAChB,aAAA,CAAe,UAAUK,CAAAA,CAAQ,KAAK,CAAA,CACvC,CAAA,CACA,KAAM,IAAA,CAAK,SAAA,CAAUe,CAAAA,CAAgB,CAAC,CAAC,CACxC,CAAC,EAED,GAAI,CAACnB,EAAS,EAAA,CAAI,CACjB,IAAMC,CAAAA,CAAY,MAAMD,CAAAA,CAAS,IAAA,EAAK,CACtC,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4BA,CAAAA,CAAS,MAAM,MAAMC,CAAS,CAAA,CAAE,CAC7E,CACA,IAAMC,EAAO,MAAMF,CAAAA,CAAS,IAAA,EAAK,CACjC,GAAI,CAACE,CAAAA,CAAK,OAAA,CACT,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4BA,CAAAA,CAAK,KAAA,EAAS,eAAe,CAAA,CAAE,CAE7E,SAAWiB,CAAAA,CAAgB,MAAA,CAAS,EAAG,CACtC,IAAMnB,CAAAA,CAAW,MAAM,MAAM,CAAA,EAAGD,CAAc,CAAA,yBAAA,CAAA,CAA6B,CAC1E,OAAQ,MAAA,CACR,OAAA,CAAS,CACR,cAAA,CAAgB,mBAChB,aAAA,CAAe,CAAA,OAAA,EAAUK,EAAQ,KAAK,CAAA,CACvC,EACA,IAAA,CAAM,IAAA,CAAK,SAAA,CAAUe,CAAe,CACrC,CAAC,CAAA,CAED,GAAI,CAACnB,EAAS,EAAA,CAAI,CACjB,IAAMC,CAAAA,CAAY,MAAMD,CAAAA,CAAS,IAAA,GACjC,MAAM,IAAI,MAAM,CAAA,0BAAA,EAA6BA,CAAAA,CAAS,MAAM,CAAA,GAAA,EAAMC,CAAS,CAAA,CAAE,CAC9E,CACA,IAAMC,CAAAA,CAAO,MAAMF,CAAAA,CAAS,IAAA,EAAK,CACjC,GAAI,CAACE,CAAAA,CAAK,OAAA,CACT,MAAM,IAAI,KAAA,CAAM,6BAA6BA,CAAAA,CAAK,KAAA,EAAS,eAAe,CAAA,CAAE,CAE9E,CACD,CC9RA,IAAMkB,EAAAA,CAAmB,IAAI,GAAA,CAAI,CAC/B,QAAA,CACA,QAAA,CACA,UACA,SAAA,CACA,OAAA,CACA,SACA,MACF,CAAC,EACKC,EAAAA,CAAoB,0BAAA,CAEbC,CAAAA,CAAN,cAAkC,KAAM,CAC7C,WAAA,CAAYC,CAAAA,CAAiB,CAC3B,MAAMA,CAAO,CAAA,CACb,IAAA,CAAK,IAAA,CAAO,sBACd,CACF,EAMO,SAASC,EAAAA,CAAuBC,CAAAA,CAAkC,CACvE,GAAI,CAACA,CAAAA,CAAK,IAAA,CACR,MAAM,IAAIH,CAAAA,CAAoB,uBAAuB,CAAA,CAEvD,GAAI,CAACG,CAAAA,CAAK,WAAA,CACR,MAAM,IAAIH,CAAAA,CAAoB,8BAA8B,EAE9D,GAAI,CAACG,EAAK,UAAA,CACR,MAAM,IAAIH,CAAAA,CAAoB,oCAAoC,CAAA,CAEpE,GAAI,OAAOG,CAAAA,CAAK,OAAA,EAAY,WAC1B,MAAM,IAAIH,CAAAA,CAAoB,iCAAiC,EAGjEI,EAAAA,CAAiBD,CAAAA,CAAK,IAAI,CAAA,CAC1BE,EAAAA,CAAoBF,EAAK,WAAW,CAAA,CACpCG,EAAAA,CAAyBH,CAAAA,CAAK,UAAU,EAC1C,CAEA,SAASC,EAAAA,CAAiBG,EAAoB,CAC5C,GAAI,OAAOA,CAAAA,EAAS,SAClB,MAAM,IAAIP,EAAoB,4BAA4B,CAAA,CAE5D,GAAIO,CAAAA,CAAK,MAAA,GAAW,CAAA,CAClB,MAAM,IAAIP,CAAAA,CAAoB,2BAA2B,CAAA,CAE3D,GAAIO,EAAK,MAAA,CAAS,EAAA,CAChB,MAAM,IAAIP,EACR,wCACF,CAAA,CAEF,GAAI,CAACD,EAAAA,CAAkB,KAAKQ,CAAI,CAAA,CAC9B,MAAM,IAAIP,EACR,sGACF,CAEJ,CAEA,SAASK,GAAoBG,CAAAA,CAA2B,CACtD,GAAI,OAAOA,GAAgB,QAAA,CACzB,MAAM,IAAIR,CAAAA,CAAoB,mCAAmC,EAEnE,GAAIQ,CAAAA,CAAY,IAAA,EAAK,CAAE,SAAW,CAAA,CAChC,MAAM,IAAIR,CAAAA,CAAoB,kCAAkC,EAElE,GAAIQ,CAAAA,CAAY,MAAA,CAAS,GAAA,CACvB,MAAM,IAAIR,CAAAA,CACR,gDACF,CAEJ,CAEA,SAASM,EAAAA,CAAyBG,CAAAA,CAAgC,CAChE,GAAI,OAAOA,CAAAA,EAAW,QAAA,EAAYA,CAAAA,GAAW,IAAA,EAAQ,MAAM,OAAA,CAAQA,CAAM,CAAA,CACvE,MAAM,IAAIT,CAAAA,CAAoB,yCAAyC,EAEzE,GAAIS,CAAAA,CAAO,OAAS,QAAA,CAClB,MAAM,IAAIT,CAAAA,CACR,kEACF,CAAA,CAGF,GAAIS,CAAAA,CAAO,UAAA,EAAc,OAAOA,CAAAA,CAAO,UAAA,EAAe,QAAA,CACpD,IAAA,GAAW,CAACC,CAAAA,CAAUC,CAAU,IAAK,MAAA,CAAO,OAAA,CAAQF,EAAO,UAAU,CAAA,CACnEG,EAAAA,CAAuBF,CAAAA,CAAUC,CAAU,CAAA,CAI/C,GAAIF,CAAAA,CAAO,QAAA,GAAa,OAAW,CACjC,GAAI,CAAC,KAAA,CAAM,QAAQA,CAAAA,CAAO,QAAQ,EAChC,MAAM,IAAIT,EAAoB,6BAA6B,CAAA,CAE7D,IAAA,IAAWa,CAAAA,IAAQJ,EAAO,QAAA,CACxB,GAAI,OAAOI,CAAAA,EAAS,SAClB,MAAM,IAAIb,CAAAA,CACR,4CACF,CAGN,CAEA,GAAIS,EAAO,oBAAA,GAAyB,MAAA,EAEhC,OAAOA,CAAAA,CAAO,oBAAA,EAAyB,SAAA,GACtC,OAAOA,EAAO,oBAAA,EAAyB,QAAA,EACtCA,CAAAA,CAAO,oBAAA,GAAyB,MAElC,MAAM,IAAIT,CAAAA,CACR,kDACF,CAGN,CAEA,SAASY,GACPF,CAAAA,CACAD,CAAAA,CACM,CACN,GAAI,OAAOA,CAAAA,EAAW,QAAA,EAAYA,IAAW,IAAA,EAAQ,KAAA,CAAM,OAAA,CAAQA,CAAM,EACvE,MAAM,IAAIT,CAAAA,CACR,CAAA,UAAA,EAAaU,CAAQ,CAAA,0BAAA,CACvB,CAAA,CAGF,GAAID,CAAAA,CAAO,IAAA,GAAS,OAAW,CAC7B,IAAMK,CAAAA,CAAQ,KAAA,CAAM,QAAQL,CAAAA,CAAO,IAAI,CAAA,CAAIA,CAAAA,CAAO,KAAO,CAACA,CAAAA,CAAO,IAAI,CAAA,CACrE,QAAWM,CAAAA,IAAQD,CAAAA,CACjB,GAAI,CAAChB,EAAAA,CAAiB,IAAIiB,CAAI,CAAA,CAC5B,MAAM,IAAIf,EACR,CAAA,cAAA,EAAiBe,CAAI,mBAAmBL,CAAQ,CAAA,gBAAA,EAC9B,MAAM,IAAA,CAAKZ,EAAgB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAC3D,CAGN,CAEA,GAAIW,EAAO,IAAA,GAAS,MAAA,EAAa,CAAC,KAAA,CAAM,QAAQA,CAAAA,CAAO,IAAI,CAAA,CACzD,MAAM,IAAIT,CAAAA,CACR,CAAA,UAAA,EAAaU,CAAQ,CAAA,uBAAA,CACvB,EAGF,GAAID,CAAAA,CAAO,YAAc,OAAOA,CAAAA,CAAO,YAAe,QAAA,CACpD,IAAA,GAAW,CAACO,CAAAA,CAAgBC,CAAgB,CAAA,GAAK,MAAA,CAAO,OAAA,CACtDR,CAAAA,CAAO,UACT,CAAA,CACEG,EAAAA,CAAuB,CAAA,EAAGF,CAAQ,IAAIM,CAAc,CAAA,CAAA,CAAIC,CAAgB,CAAA,CAIxER,CAAAA,CAAO,QACL,KAAA,CAAM,OAAA,CAAQA,CAAAA,CAAO,KAAK,EAC5BA,CAAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,CAACS,EAAYC,CAAAA,GAAU,CAC1CP,EAAAA,CAAuB,CAAA,EAAGF,CAAQ,CAAA,CAAA,EAAIS,CAAK,IAAKD,CAAU,EAC5D,CAAC,CAAA,CAEDN,EAAAA,CAAuB,CAAA,EAAGF,CAAQ,KAAMD,CAAAA,CAAO,KAAK,GAG1D,CAKO,SAASW,GACdjB,CAAAA,CACuC,CACvC,OAAO,CACL,KAAMA,CAAAA,CAAK,IAAA,CACX,YAAaA,CAAAA,CAAK,WAAA,CAClB,WAAYA,CAAAA,CAAK,UACnB,CACF,CC3IA,IAAMkB,EAAAA,CAAwB,IAAA,CACxBC,EAAAA,CAA0B,GAAA,CAC1BC,GAAyB,GAAA,CAE/B,SAASC,EAAAA,CAAkBpD,CAAAA,CAA2BU,EAA+B,CACnF,GAAIV,EAAO,YAAA,CAAc,CACvB,IAAMqD,CAAAA,CAAM,IAAI,GAAA,CAAIrD,CAAAA,CAAO,YAAY,CAAA,CACvC,OAAAqD,CAAAA,CAAI,QAAA,CAAW,wBAAwB3C,CAAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAA,CAAA,CAC/D2C,EAAI,YAAA,CAAa,GAAA,CAAI,OAAQ,MAAM,CAAA,CACnCA,EAAI,YAAA,CAAa,GAAA,CAAI,SAAA,CAAWpD,CAAAA,EAAmB,CAAA,CACnDoD,CAAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAe3C,CAAAA,CAAQ,KAAK,CAAA,CAC1C2C,CAAAA,CAAI,UACb,CAKA,IAAMC,CAAAA,CAHUvD,CAAAA,CAAkBC,CAAM,CAAA,CAEjB,OAAA,CAAQ,QAAA,CAAU,EAAE,EACnB,OAAA,CAAQ,SAAA,CAAW,MAAM,CAAA,CAAE,OAAA,CAAQ,SAAU,KAAK,CAAA,CACpEG,CAAAA,CAASF,CAAAA,GACf,OAAO,CAAA,EAAGqD,CAAQ,CAAA,qBAAA,EAAwB5C,CAAAA,CAAQ,OAAO,SAAS,CAAA,oBAAA,EAAuB,kBAAA,CAAmBP,CAAM,CAAC,CAAA,aAAA,EAAgB,kBAAA,CAAmBO,CAAAA,CAAQ,KAAK,CAAC,CAAA,CACtK,CA8FA,SAAS6C,EAAAA,CACP7C,EACqB,CACrB,IAAM8C,EAAI9C,CAAAA,EAAS,MAAA,CAAO,SAC1B,OAAK8C,CAAAA,CACE,CACL,UAAA,CAAYA,EAAE,WAAA,CACd,eAAA,CAAiBA,CAAAA,CAAE,iBAAA,CACnB,eAAgBA,CAAAA,CAAE,eAAA,CAClB,kBAAA,CAAoBA,CAAAA,CAAE,oBACtB,qBAAA,CAAuBA,CAAAA,CAAE,wBACzB,qBAAA,CAAuBA,CAAAA,CAAE,wBACzB,UAAA,CAAYA,CAAAA,CAAE,WAAA,CACd,oBAAA,CAAsBA,EAAE,qBAAA,CACxB,eAAA,CAAiBA,CAAAA,CAAE,gBAAA,CACnB,YAAaA,CAAAA,CAAE,YAAA,CACf,eAAA,CAAiBA,CAAAA,CAAE,gBACrB,CAAA,CAbe,IAcjB,CAuBA,eAAeC,EAAAA,CACbC,EACAhD,CAAAA,CACAiD,CAAAA,CACAC,CAAAA,CACsE,CACtE,IAAMC,CAAAA,CAAU,IAAI,WAAA,CACdC,CAAAA,CAAkB,KAAK,GAAA,EAAI,CAC7BC,CAAAA,CAAmB,EAAA,CACnBC,EAAgC,IAAA,CAC9BC,CAAAA,CAA6B,EAAC,CAChCC,CAAAA,CAGAC,EACAC,EAAAA,CAAmB,KAAA,CAGnBC,CAAAA,CAA8B,QAAA,CAC9BC,EAAsB,EAAA,CACtBC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,EACAC,CAAAA,CAEAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,EAEAC,CAAAA,CACAC,CAAAA,CACAC,EACAC,CAAAA,CACAC,CAAAA,CAEAC,GAAmB,KAAA,CAEnBC,CAAAA,CAAa,EAAA,CAEXC,EAAAA,CAAW7E,EAAQ,MAAA,CAAO,QAAA,CAE1B8E,CAAAA,CAAgB,IAAM,EACtBlB,CAAAA,EAAuBD,CAAAA,GAAqB,MAAA,IAC9CJ,CAAAA,CAAO,KAAK,CACV,IAAA,CAAMI,EACN,OAAA,CAASC,CAAAA,CACT,SAAUC,CAAAA,CACV,eAAA,CAAiBC,CAAAA,CACjB,OAAA,CAASC,EACT,MAAA,CAAQC,CAAAA,CACR,SAAA,CAAWC,CAAAA,CACX,SAAUC,CAAAA,CACV,WAAA,CAAaC,CAAAA,CACb,WAAA,CAAaC,EACb,QAAA,CAAUC,CAAAA,CACV,SAAUC,CAAAA,CACV,aAAA,CAAeC,EACf,UAAA,CAAYC,CAAAA,CACZ,aAAA,CAAeC,CAAAA,CACf,SAAUC,CACZ,CAAC,EACDd,CAAAA,CAAsB,EAAA,CACtBC,EAAkB,MAAA,CAClBC,CAAAA,CAAyB,MAAA,CACzBC,CAAAA,CAAiB,OACjBC,CAAAA,CAAoB,MAAA,CACpBC,EAAmB,MAAA,CACnBC,CAAAA,CAAkB,OAClBC,CAAAA,CAAqB,MAAA,CACrBC,CAAAA,CAAqB,MAAA,CACrBC,EAAkB,MAAA,CAClBC,CAAAA,CAAkB,MAAA,CAClBC,CAAAA,CAAuB,OACvBC,CAAAA,CAAoB,MAAA,CACpBC,CAAAA,CAAuB,MAAA,CACvBC,EAAkB,MAAA,EAEtB,CAAA,CAEMK,EAAqB,IAAwB,CACjD,IAAMC,CAAAA,CAAUzB,CAAAA,CAAO,GAAA,CAAK0B,CAAAA,EAAMA,CAA8B,CAAA,CAChE,OAAA,CAAIrB,CAAAA,EAAuBD,CAAAA,GAAqB,SAC9CqB,CAAAA,CAAQ,IAAA,CAAK,CACX,IAAA,CAAMrB,EACN,OAAA,CAASC,CAAAA,CACT,SAAUC,CAAAA,CACV,eAAA,CAAiBC,EACjB,OAAA,CAASC,CAAAA,CACT,MAAA,CAAQC,CAAAA,CACR,UAAWC,CAAAA,CACX,QAAA,CAAUC,CAAAA,CACV,WAAA,CAAaC,EACb,WAAA,CAAaC,CAAAA,CACb,QAAA,CAAUC,CAAAA,CACV,SAAUC,CAAAA,CACV,aAAA,CAAeC,EACf,UAAA,CAAYC,CAAAA,CACZ,cAAeC,CAAAA,CACf,QAAA,CAAUC,CACZ,CAAC,EAEIM,CACT,CAAA,CAEME,EAAyB,IAAM,CACnC,IAAMC,CAAAA,CAAgBJ,CAAAA,EAAmB,CAEzC,GAAKzB,EAmBHJ,CAAAA,CAAU,eAAA,CAAgB,CACxB,EAAA,CAAII,CAAAA,CACJ,YAAaD,CAAAA,CACb,SAAA,CAAW8B,CAAAA,CACX,gBAAA,CAAA3B,CACF,CAAC,CAAA,CAAA,KAxBkB,CACnBF,CAAAA,CAAiB,aAAa,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CACxC,IAAM8B,CAAAA,CAAgC,CACpC,GAAI9B,CAAAA,CACJ,WAAA,CAAaD,EACb,WAAA,CAAa,CACX,EAAA,CAAI,WAAA,CACJ,KACEwB,EAAAA,EAAU,WAAA,EAAe7E,CAAAA,CAAQ,MAAA,CAAO,eAC1C,IAAA,CAAM,WAAA,CACN,SAAA,CAAW6E,EAAAA,EAAU,gBACvB,CAAA,CACA,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,aAAY,CAClC,WAAA,CAAa,IAAA,CACb,SAAA,CAAWM,EACX,gBAAA,CAAA3B,CACF,CAAA,CACAN,CAAAA,CAAU,gBAAgBkC,CAAY,EACxC,CAQF,CAAA,CAEA,OAAa,CACX,GAAM,CAAE,IAAA,CAAAC,CAAAA,CAAM,MAAAC,CAAM,CAAA,CAAI,MAAMtC,CAAAA,CAAO,MAAK,CAC1C,GAAIqC,EAAM,MAEV,IAAME,EAAWpC,CAAAA,CAAQ,MAAA,CAAOmC,CAAAA,CAAO,CAAE,OAAQ,IAAK,CAAC,EAEjDE,CAAAA,CAAAA,CADOZ,CAAAA,CAAaW,GACP,KAAA,CAAM;AAAA,CAAI,CAAA,CAExBA,EAAS,QAAA,CAAS;AAAA,CAAI,CAAA,CAGzBX,EAAa,EAAA,CAFbA,CAAAA,CAAaY,EAAM,GAAA,EAAI,EAAK,EAAA,CAK9B,IAAA,IAAWC,CAAAA,IAAQD,CAAAA,CAAO,CACxB,GAAI,CAACC,EAAK,UAAA,CAAW,QAAQ,EAAG,SAEhC,IAAM3F,CAAAA,CAAO2F,CAAAA,CAAK,KAAA,CAAM,CAAC,EACzB,GAAI3F,CAAAA,GAAS,SAAU,MAEvB,GAAI,CACF,IAAM4F,CAAAA,CAAS,IAAA,CAAK,KAAA,CAAM5F,CAAI,CAAA,CAE9B,GAAI4F,CAAAA,CAAO,IAAA,GAAS,kBAAmB,CAErC,GAAIA,EAAO,eAAA,CAAiB,CAAA,CACtB9B,CAAAA,EAAuBD,CAAAA,GAAqB,QAAA,IAC9CmB,CAAAA,GACAnB,CAAAA,CAAmB,QAAA,CAAA,CAGrBJ,EAAO,IAAA,CAAK,CACV,KAAM,MAAA,CACN,OAAA,CAAS,EAAA,CACT,QAAA,CAAUmC,CAAAA,CAAO,SAAA,CACjB,gBAAiBA,CAAAA,CAAO,gBAAA,CACxB,OAAQ,SAAA,CACR,SAAA,CAAWA,EAAO,UACpB,CAAC,CAAA,CACDR,CAAAA,EAAuB,CACvB,QACF,CAGA,GAAIQ,CAAAA,CAAO,kBAAmB,CAC5B,IAAA,IAASC,EAAIpC,CAAAA,CAAO,MAAA,CAAS,CAAA,CAAGoC,CAAAA,EAAK,CAAA,CAAGA,CAAAA,EAAAA,CAAK,CAC3C,IAAMC,CAAAA,CAAQrC,CAAAA,CAAOoC,CAAC,CAAA,CACtB,GACEC,EAAM,IAAA,GAAS,MAAA,EACfA,CAAAA,CAAM,QAAA,GAAaF,CAAAA,CAAO,SAAA,GACzBA,EAAO,UAAA,GAAe,KAAA,CAAA,EACrBE,EAAM,SAAA,GAAcF,CAAAA,CAAO,YAC7B,CACAnC,CAAAA,CAAOoC,CAAC,CAAA,CAAE,MAAA,CAAS,WAAA,CACnB,KACF,CACF,CACAT,GAAuB,CACvB,QACF,CAGA,GAAIQ,CAAAA,CAAO,cAAA,CAAgB,CACzB,IAAA,IAASC,CAAAA,CAAIpC,EAAO,MAAA,CAAS,CAAA,CAAGoC,GAAK,CAAA,CAAGA,CAAAA,EAAAA,CAAK,CAC3C,IAAMC,CAAAA,CAAQrC,CAAAA,CAAOoC,CAAC,CAAA,CACtB,GACEC,EAAM,IAAA,GAAS,MAAA,EACfA,CAAAA,CAAM,QAAA,GAAaF,CAAAA,CAAO,SAAA,GACzBA,EAAO,UAAA,GAAe,KAAA,CAAA,EACrBE,CAAAA,CAAM,SAAA,GAAcF,CAAAA,CAAO,UAAA,CAAA,CAC7B,CACAnC,CAAAA,CAAOoC,CAAC,EAAE,MAAA,CAAS,WAAA,CACnB,KACF,CACF,CACAT,CAAAA,EAAuB,CACvB,QACF,CAGA,GAAIQ,CAAAA,CAAO,iBAAA,CAAmB,CAC5BlC,CAAAA,CAAmBkC,CAAAA,CAAO,kBAAkB,GAAA,CACzC,CAAA,GAA0C,CACzC,EAAA,CAAI,CAAA,CAAE,MAAA,CACN,MAAO,CAAA,CAAE,KAAA,CACT,MAAO,CAAA,CAAE,MACX,EACF,CAAA,CACAR,CAAAA,EAAuB,CACvB,QACF,CAGA,GAAIQ,EAAO,aAAA,CAAe,CAAA,CACpB9B,CAAAA,EAAuBD,CAAAA,GAAqB,QAAA,IAC9CmB,CAAAA,GACAnB,CAAAA,CAAmB,QAAA,CAAA,CAErBJ,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,aACN,OAAA,CAAS,EAAA,CACT,WAAYmC,CAAAA,CAAO,WAAA,CACnB,WAAY,CAAA,CAAA,CACZ,QAAA,CAAU,CACR,UAAA,CAAYA,CAAAA,CAAO,WAAA,CACnB,WAAYA,CAAAA,CAAO,WAAA,EAAe,EAAC,CACnC,aAAA,CAAeA,EAAO,cAAA,EAAkB,CAAA,CACxC,UAAA,CAAYA,CAAAA,CAAO,WAAA,EAAe,CACpC,CACF,CAAgC,CAAA,CAChCR,GAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,gBAAA,CAAkB,CAC3BnC,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,eAAA,CACN,QAAS,EAAA,CACT,UAAA,CAAYmC,EAAO,WAAA,CACnB,UAAA,CAAY,CAAA,CAAA,CACZ,QAAA,CAAU,CACR,UAAA,CAAYA,EAAO,WAAA,CACnB,UAAA,CAAY,EAAC,CACb,aAAA,CAAe,EACf,UAAA,CAAY,CAAA,CACZ,YAAA,CAAcA,CAAAA,CAAO,aAAA,EAAiB,GACtC,OAAA,CAASA,CAAAA,CAAO,QAChB,aAAA,CAAeA,CAAAA,CAAO,cACxB,CACF,CAAgC,CAAA,CAChCR,CAAAA,EAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,0BAA2B,CACpCnC,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,wBAAA,CACN,OAAA,CAAS,EAAA,CACT,SAAA,CAAWmC,EAAO,UAAA,CAClB,UAAA,CAAYA,CAAAA,CAAO,WAAA,CACnB,UAAA,CAAY,CAAA,CAAA,CACZ,oBAAqB,CACnB,SAAA,CAAWA,CAAAA,CAAO,UAAA,CAClB,UAAA,CAAYA,CAAAA,CAAO,YACnB,WAAA,CAAaA,CAAAA,CAAO,WACtB,CACF,CAAgC,EAChCR,CAAAA,EAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,6BAA8B,CACvCnC,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,4BACN,OAAA,CAAS,EAAA,CACT,SAAA,CAAWmC,CAAAA,CAAO,UAAA,CAClB,UAAA,CAAYA,EAAO,WAAA,CACnB,UAAA,CAAY,GACZ,OAAA,CAASA,CAAAA,CAAO,QAChB,mBAAA,CAAqB,CACnB,SAAA,CAAWA,CAAAA,CAAO,UAAA,CAClB,UAAA,CAAYA,EAAO,WAAA,CACnB,OAAA,CAASA,CAAAA,CAAO,OAAA,CAChB,MAAA,CAAQA,CAAAA,CAAO,OACf,KAAA,CAAOA,CAAAA,CAAO,KAAA,CACd,aAAA,CAAeA,CAAAA,CAAO,cACxB,CACF,CAAgC,CAAA,CAChCR,GAAuB,CACvB,QACF,CAMA,GAAIQ,CAAAA,CAAO,uBAAA,CAAyB,CAClCf,EAAAA,CAAmB,CAAA,CAAA,CAAA,CACff,GAAuBD,CAAAA,GAAqB,QAAA,IAC9CmB,GAAc,CACdnB,CAAAA,CAAmB,UAErBJ,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,sBAAA,CACN,OAAA,CAAS,GACT,YAAA,CAAc,CAAA,CAChB,CAAqB,CAAA,CACrB2B,CAAAA,GACA,QACF,CAEA,GAAIQ,CAAAA,CAAO,YAAA,EAAgBA,CAAAA,CAAO,gBAAiB,CAEjD,IAAMG,CAAAA,CAActC,CAAAA,CAAO,SAAA,CACxB0B,CAAAA,EAAMA,EAAE,IAAA,GAAS,UAAA,EAAcA,CAAAA,CAAE,YACpC,CAAA,CACIY,CAAAA,EAAe,EACjBtC,CAAAA,CAAOsC,CAAW,EAAI,CACpB,GAAGtC,EAAOsC,CAAW,CAAA,CACrB,OAAA,CAAA,CAAUtC,CAAAA,CAAOsC,CAAW,CAAA,CAAE,SAAW,EAAA,EAAMH,CAAAA,CAAO,eACxD,CAAA,CAEAnC,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,UAAA,CACN,OAAA,CAASmC,CAAAA,CAAO,eAAA,CAChB,aAAc,CAAA,CAChB,CAAqB,EAEvBR,CAAAA,EAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,gCAAA,CAAkC,CAE3C,IAAMI,EAAcvC,CAAAA,CAAO,SAAA,CACxB0B,GAAMA,CAAAA,CAAE,IAAA,GAAS,wBAA0BA,CAAAA,CAAE,YAChD,CAAA,CACIa,CAAAA,EAAe,CAAA,CACjBvC,CAAAA,CAAOuC,CAAW,CAAA,CAAI,CACpB,GAAGvC,CAAAA,CAAOuC,CAAW,EACrB,mBAAA,CAAqBJ,CAAAA,CAAO,SAAA,EAAa,EAC3C,CAAA,CAEAnC,EAAO,IAAA,CAAK,CACV,KAAM,sBAAA,CACN,OAAA,CAAS,GACT,YAAA,CAAc,CAAA,CAAA,CACd,mBAAA,CAAqBmC,CAAAA,CAAO,SAAA,EAAa,EAC3C,CAAqB,CAAA,CAEvBR,GAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,8BAAA,CAET,SAGF,GAAIA,CAAAA,CAAO,kBAAmB,CAC5BnC,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,gBAAA,CACN,QAAS,EAAA,CACT,YAAA,CAAc,CAAA,CAAA,CACd,YAAA,CAAc,CACZ,EAAA,CAAImC,EAAO,WAAA,CACX,IAAA,CAAMA,EAAO,aAAA,CACb,IAAA,CAAMA,EAAO,IAAA,CACb,MAAA,CAAQ,SACV,CACF,CAAqB,CAAA,CACrBR,GAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,qBAAsB,CAE/B,IAAMK,CAAAA,CAAgBxC,CAAAA,CAAO,SAAA,CAC1B0B,CAAAA,EACCA,EAAE,IAAA,GAAS,gBAAA,EACXA,EAAE,YAAA,EAAc,EAAA,GAAOS,EAAO,WAClC,CAAA,CACIK,CAAAA,GAAkB,CAAA,CAAA,EAAMxC,CAAAA,CAAOwC,CAAa,EAAE,YAAA,GAChDxC,CAAAA,CAAOwC,CAAa,CAAA,CAAI,CACtB,GAAGxC,EAAOwC,CAAa,CAAA,CACvB,OAAA,CAASL,CAAAA,CAAO,QAAA,EAAY,EAC9B,GAEFR,CAAAA,EAAuB,CACvB,QACF,CAEA,GAAIQ,EAAO,oBAAA,CAAsB,CAC/BnC,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,oBACN,OAAA,CAAS,EAAA,CACT,aAAc,CAAA,CAAA,CACd,YAAA,CAAc,CACZ,EAAA,CAAImC,CAAAA,CAAO,WAAA,CACX,IAAA,CAAMA,CAAAA,CAAO,aAAA,CACb,OAAQ,WAAA,CACR,MAAA,CAAQA,EAAO,MAAA,CACf,aAAA,CAAeA,EAAO,cACxB,CACF,CAAqB,CAAA,CACrBR,CAAAA,EAAuB,CACvB,QACF,CAEA,GAAIQ,CAAAA,CAAO,kBAAA,CAAoB,CAC7BnC,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,iBAAA,CACN,OAAA,CAAS,EAAA,CACT,YAAA,CAAc,GACd,YAAA,CAAc,CACZ,GAAImC,CAAAA,CAAO,WAAA,CACX,KAAMA,CAAAA,CAAO,aAAA,CACb,MAAA,CAAQ,QAAA,CACR,KAAA,CAAOA,CAAAA,CAAO,KAChB,CACF,CAAqB,EACrBR,CAAAA,EAAuB,CACvB,QACF,CAGA,GAAIQ,CAAAA,CAAO,kBAAA,EAAsBf,EAAAA,CAAkB,CACjDpB,EAAO,IAAA,CAAK,CACV,KAAM,WAAA,CACN,OAAA,CAAS,GACT,YAAA,CAAc,CAAA,CAAA,CACd,WAAA,CAAa,CAAA,CACf,CAAqB,CAAA,CACrB2B,GAAuB,CACvB,QACF,CAGA,GAAIQ,CAAAA,CAAO,SAAA,CAAW,CACpB,IAAMM,CAAAA,CAAcN,CAAAA,CAAO,SAAA,CAC3BxB,CAAAA,CAAkB,CAChB,KAAM8B,CAAAA,CAAY,IAAA,EAAQ,GAC1B,SAAA,CAAWA,CAAAA,CAAY,WAAa,EAAA,CACpC,QAAA,CAAA,CAAWA,CAAAA,CAAY,QAAA,EAAY,EAAC,EAAG,IAAKC,CAAAA,GAAa,CACvD,GAAI,MAAA,CAAOA,CAAAA,CAAG,EAAE,CAAA,CAChB,WAAA,CAAaA,CAAAA,CAAG,WAAA,CAChB,cAAA,CAAgBA,CAAAA,CAAG,eACnB,YAAA,CAAcA,CAAAA,CAAG,aACjB,MAAA,CAAQ,SACV,EAAE,CAAA,CACF,cAAA,CAAgBD,CAAAA,CAAY,QAAA,EAAU,MAAA,EAAU,CAAA,CAChD,mBAAoB,CAAA,CACpB,eAAA,CAAiB,CAAA,CACjB,mBAAA,CAAqB,CACvB,EACF,CAGIN,CAAAA,CAAO,YAAA,GACTvB,CAAAA,CAAqBuB,CAAAA,CAAO,YAAA,CAAA,CAI1BA,CAAAA,CAAO,qBACTtB,CAAAA,CAAqB,CAAA,CAAA,CAAA,CAEnBsB,EAAO,SAAA,GACTrB,CAAAA,CAAkB,IAIhBqB,CAAAA,CAAO,SAAA,GAAWpB,CAAAA,CAAkBoB,CAAAA,CAAO,SAAA,CAAA,CAC3CA,CAAAA,CAAO,iBAAmB,KAAA,CAAA,GAAWnB,CAAAA,CAAuBmB,EAAO,cAAA,CAAA,CACnEA,CAAAA,CAAO,cAAgB,KAAA,CAAA,GAAWlB,CAAAA,CAAoBkB,CAAAA,CAAO,WAAA,CAAA,CAC7DA,CAAAA,CAAO,cAAA,GAAgBjB,EAAuBiB,CAAAA,CAAO,cAAA,CAAA,CACrDA,EAAO,QAAA,GAAUhB,CAAAA,CAAkBgB,EAAO,QAAA,CAAA,CAG9C,IAAIQ,CAAAA,CAA0B,QAAA,CA8B9B,GA7BIR,CAAAA,CAAO,YACTQ,CAAAA,CAAe,UAAA,CAEfR,CAAAA,CAAO,WAAA,EACPA,CAAAA,CAAO,gBAAA,EACPA,EAAO,aAAA,CAEPQ,CAAAA,CAAe,UAAA,CAEfR,CAAAA,CAAO,gBAAA,EACPA,CAAAA,CAAO,qBACPA,CAAAA,CAAO,iBAAA,CAEPQ,EAAe,SAAA,CACNR,CAAAA,CAAO,qBAChBQ,CAAAA,CAAe,UAAA,CAAA,CAGbA,CAAAA,GAAiBvC,CAAAA,GACnBmB,CAAAA,EAAc,CACdnB,EAAmBuC,CAAAA,CAAAA,CAGjBR,CAAAA,CAAO,YAAW7B,CAAAA,CAAkB6B,CAAAA,CAAO,WAC3CA,CAAAA,CAAO,OAAA,GAAY,KAAA,CAAA,GAAW3B,CAAAA,CAAiB2B,CAAAA,CAAO,OAAA,CAAA,CACtDA,EAAO,UAAA,GAAe,KAAA,CAAA,GACxBzB,EAAmByB,CAAAA,CAAO,UAAA,CAAA,CAGxBQ,IAAiB,UAAA,CAAY,CAC/BtC,CAAAA,EAAuB8B,CAAAA,CAAO,KAAA,EAAS,EAAA,CACvC,IAAMS,CAAAA,CAAQvC,CAAAA,CAAoB,KAAA,CAChC,qCACF,CAAA,CACIuC,CAAAA,GACFvC,EAAsBuC,CAAAA,CAAM,CAAC,CAAA,CAC1B,OAAA,CAAQ,MAAA,CAAQ;AAAA,CAAI,EACpB,OAAA,CAAQ,MAAA,CAAQ,GAAG,CAAA,CACnB,QAAQ,MAAA,CAAQ,GAAI,CAAA,CACpB,OAAA,CAAQ,QAAS,IAAI,CAAA,EAE5B,CAAA,KAAA,GAAWD,CAAAA,GAAiB,SAAU,CACpC,IAAME,CAAAA,CAAeV,CAAAA,CAAO,OAAO,IAAA,EAAK,EAAK,EAAA,CACvCW,CAAAA,CAAqBhD,EAAiB,IAAA,EAAK,CAG7C+C,CAAAA,EACAC,CAAAA,EACAD,IAAiBC,CAAAA,GAGnBhD,CAAAA,EAAoBqC,EAAO,KAAA,EAAS,EAAA,EAExC,MACE9B,CAAAA,EAAuB8B,CAAAA,CAAO,KAAA,EAAS,EAAA,CAIrCA,EAAO,mBAAA,EACTxC,CAAAA,CAAU,qBAAA,CACRD,CAAAA,CACAyC,EAAO,mBACT,CAAA,CAGFR,CAAAA,GACF,SAISQ,CAAAA,CAAO,IAAA,GAAS,cAAe,CAEtCrC,CAAAA,EAAoBqC,EAAO,KAAA,EAAS,EAAA,CAEpC,IAAMY,CAAAA,CAAoB/C,EAAO,IAAA,CAC9B0B,CAAAA,EAAMA,CAAAA,CAAE,IAAA,GAAS,aACpB,CAAA,CACIqB,CAAAA,CACFA,CAAAA,CAAkB,OAAA,EAAWZ,EAAO,KAAA,EAAS,EAAA,CAE7CnC,EAAO,IAAA,CAAK,CACV,KAAM,aAAA,CACN,OAAA,CAASmC,CAAAA,CAAO,KAAA,EAAS,GACzB,YAAA,CAAc,kBAChB,CAAqB,CAAA,CAEvBR,IACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,IAAA,GAAS,kBAEzBnC,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,iBAAA,CACN,QAASmC,CAAAA,CAAO,OAAA,EAAW,EAAA,CAC3B,YAAA,CAAc,kBAChB,CAAqB,CAAA,CACrBR,CAAAA,EAAuB,CAAA,KAAA,GACdQ,EAAO,IAAA,GAAS,kBAAA,CAAoB,CAC7C,IAAMa,EAAqC,CACzC,SAAA,CAAWb,EAAO,WAAA,CAClB,SAAA,CAAW,OACX,QAAA,CAAUA,CAAAA,CAAO,SAAA,CACjB,MAAA,CAAQA,EAAO,MAAA,CACf,OAAA,CAASA,CAAAA,CAAO,OAAA,CAChB,WAAYA,CAAAA,CAAO,WAAA,CACnB,QAAA,CAAUA,CAAAA,CAAO,SACjB,KAAA,CAAOA,CAAAA,CAAO,MACd,UAAA,CAAYA,CAAAA,CAAO,WACrB,CAAA,CACMG,CAAAA,CAActC,CAAAA,CAAO,SAAA,CACxB0B,GACCA,CAAAA,CAAE,IAAA,GAAS,gBAAA,EACXA,CAAAA,CAAE,YAAcS,CAAAA,CAAO,WAC3B,CAAA,CACIG,CAAAA,EAAe,EACjBtC,CAAAA,CAAOsC,CAAW,EAAE,iBAAA,CAAoBU,CAAAA,CAExChD,EAAO,IAAA,CAAK,CACV,IAAA,CAAM,gBAAA,CACN,QAAS,EAAA,CACT,SAAA,CAAWmC,CAAAA,CAAO,WAAA,CAClB,kBAAmBa,CAAAA,CACnB,YAAA,CAAc,kBAChB,CAAqB,EAEvBrB,CAAAA,GACF,SAAWQ,CAAAA,CAAO,IAAA,GAAS,mBAAoB,CAC7C,IAAMc,CAAAA,CAAuC,CAC3C,UAAWd,CAAAA,CAAO,WAAA,CAClB,SAAA,CAAW,MAAA,CACX,SAAUA,CAAAA,CAAO,SAAA,CACjB,MAAA,CAAQA,CAAAA,CAAO,OACf,SAAA,CAAWA,CAAAA,CAAO,WAClB,SAAA,CAAWA,CAAAA,CAAO,WAClB,KAAA,CAAOA,CAAAA,CAAO,KAAA,CACd,UAAA,CAAYA,EAAO,WACrB,CAAA,CACMG,CAAAA,CAActC,CAAAA,CAAO,UACxB0B,CAAAA,EACCA,CAAAA,CAAE,IAAA,GAAS,gBAAA,EACXA,EAAE,SAAA,GAAcS,CAAAA,CAAO,WAC3B,CAAA,CACIG,CAAAA,EAAe,EACjBtC,CAAAA,CAAOsC,CAAW,CAAA,CAAE,iBAAA,CAAoBW,EAExCjD,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,iBACN,OAAA,CAAS,EAAA,CACT,SAAA,CAAWmC,CAAAA,CAAO,YAClB,iBAAA,CAAmBc,CAAAA,CACnB,aAAc,kBAChB,CAAqB,EAEvBtB,CAAAA,GACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,OAAS,mBAAA,CAAqB,CAC9C,IAAMe,CAAAA,CAAwC,CAC5C,SAAA,CAAWf,CAAAA,CAAO,WAAA,CAClB,SAAA,CAAW,QACX,QAAA,CAAUA,CAAAA,CAAO,UACjB,MAAA,CAAQA,CAAAA,CAAO,OACf,KAAA,CAAOA,CAAAA,CAAO,KAAA,CACd,UAAA,CAAYA,EAAO,WACrB,CAAA,CACMG,CAAAA,CAActC,CAAAA,CAAO,UACxB0B,CAAAA,EACCA,CAAAA,CAAE,IAAA,GAAS,gBAAA,EACXA,EAAE,SAAA,GAAcS,CAAAA,CAAO,WAC3B,CAAA,CACIG,CAAAA,EAAe,EACjBtC,CAAAA,CAAOsC,CAAW,CAAA,CAAE,iBAAA,CAAoBY,EAExClD,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,iBACN,OAAA,CAAS,EAAA,CACT,SAAA,CAAWmC,CAAAA,CAAO,YAClB,iBAAA,CAAmBe,CAAAA,CACnB,aAAc,kBAChB,CAAqB,EAEvBvB,CAAAA,GACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,OAAS,aAAA,CAAe,CACxC,IAAMgB,CAAAA,CAA8B,CAClC,SAAA,CAAWhB,CAAAA,CAAO,WAAA,CAClB,OAAA,CAASA,EAAO,OAAA,CAChB,WAAA,CAAaA,EAAO,WAAA,CACpB,MAAA,CAAQA,EAAO,MAAA,CACf,MAAA,CAAQA,CAAAA,CAAO,MAAA,CACf,OAAQA,CAAAA,CAAO,MAAA,CACf,QAAA,CAAUA,CAAAA,CAAO,UACjB,UAAA,CAAYA,CAAAA,CAAO,WACrB,CAAA,CACMG,EAActC,CAAAA,CAAO,SAAA,CACxB0B,CAAAA,EACCA,CAAAA,CAAE,OAAS,UAAA,EAAcA,CAAAA,CAAE,SAAA,GAAcS,CAAAA,CAAO,WACpD,CAAA,CACIG,CAAAA,EAAe,CAAA,CACjBtC,CAAAA,CAAOsC,CAAW,CAAA,CAAE,YAAA,CAAea,CAAAA,CAEnCnD,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,WACN,OAAA,CAAS,EAAA,CACT,UAAWmC,CAAAA,CAAO,WAAA,CAClB,YAAA,CAAcgB,CAAAA,CACd,aAAc,kBAChB,CAAqB,CAAA,CAEvBxB,CAAAA,GACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,IAAA,GAAS,eAAA,CAAiB,CAC1C,IAAMiB,CAAAA,CAAqC,CACzC,SAAA,CAAWjB,CAAAA,CAAO,YAClB,IAAA,CAAMA,CAAAA,CAAO,IAAA,CACb,OAAA,CAASA,EAAO,OAAA,CAChB,IAAA,CAAMA,CAAAA,CAAO,IAAA,CACb,OAAQA,CAAAA,CAAO,MAAA,CACf,OAAA,CAAA,CAAUA,CAAAA,CAAO,SAAW,EAAC,EAAG,IAAKkB,CAAAA,GAAY,CAC/C,SAAUA,CAAAA,CAAE,SAAA,CACZ,UAAA,CAAYA,CAAAA,CAAE,YACd,OAAA,CAASA,CAAAA,CAAE,OACb,CAAA,CAAE,EACF,UAAA,CAAYlB,CAAAA,CAAO,WAAA,EAAe,CAAA,CAClC,MAAOA,CAAAA,CAAO,KAAA,CACd,WAAYA,CAAAA,CAAO,WACrB,EACMG,CAAAA,CAActC,CAAAA,CAAO,SAAA,CACxB0B,CAAAA,EACCA,EAAE,IAAA,GAAS,gBAAA,EACXA,CAAAA,CAAE,SAAA,GAAcS,EAAO,WAC3B,CAAA,CACIG,CAAAA,EAAe,CAAA,CACjBtC,EAAOsC,CAAW,CAAA,CAAE,kBAAoBc,CAAAA,CAExCpD,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,gBAAA,CACN,OAAA,CAAS,GACT,SAAA,CAAWmC,CAAAA,CAAO,WAAA,CAClB,iBAAA,CAAmBiB,EACnB,YAAA,CAAc,kBAChB,CAAqB,CAAA,CAEvBzB,IACF,CAAA,KAAA,GACEQ,EAAO,IAAA,GAAS,mBAAA,EAChBA,EAAO,IAAA,GAAS,kBAAA,CAChB,CACA,IAAMmB,EAAmC,CACvC,SAAA,CAAWnB,CAAAA,CAAO,WAAA,CAClB,UACEA,CAAAA,CAAO,IAAA,GAAS,mBAAA,CAAsB,QAAA,CAAW,QACnD,KAAA,CAAOA,CAAAA,CAAO,MACd,GAAA,CAAKA,CAAAA,CAAO,IACZ,MAAA,CAAQA,CAAAA,CAAO,MAAA,CACf,OAAA,CAASA,EAAO,OAAA,CAChB,OAAA,CAASA,CAAAA,CAAO,OAAA,CAChB,MAAOA,CAAAA,CAAO,KAAA,CACd,UAAA,CAAYA,CAAAA,CAAO,WACrB,CAAA,CACMG,CAAAA,CAActC,EAAO,SAAA,CACxB0B,CAAAA,EACCA,EAAE,IAAA,GAAS,eAAA,EACXA,CAAAA,CAAE,SAAA,GAAcS,EAAO,WAC3B,CAAA,CACIG,CAAAA,EAAe,CAAA,CACjBtC,EAAOsC,CAAW,CAAA,CAAE,gBAAA,CAAmBgB,CAAAA,CAEvCtD,EAAO,IAAA,CAAK,CACV,KAAM,eAAA,CACN,OAAA,CAAS,GACT,SAAA,CAAWmC,CAAAA,CAAO,WAAA,CAClB,gBAAA,CAAkBmB,EAClB,YAAA,CAAc,kBAChB,CAAqB,CAAA,CAEvB3B,IACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,IAAA,GAAS,wBAAyB,CAClD,IAAMoB,EAA6B,CACjC,UAAA,CAAYpB,EAAO,WAAA,CACnB,YAAA,CAAcA,CAAAA,CAAO,aAAA,CACrB,YAAaA,CAAAA,CAAO,WAAA,CACpB,MAAA,CAAQA,CAAAA,CAAO,OACf,MAAA,CAAQ,SAAA,CACR,YAAA,CAAc,EAChB,CAAA,CACAnC,CAAAA,CAAO,KAAK,CACV,IAAA,CAAM,WACN,OAAA,CAAS,EAAA,CACT,SAAA,CAAWmC,CAAAA,CAAO,mBAClB,YAAA,CAAcoB,CAAAA,CACd,YAAA,CAAc,kBAChB,CAAqB,CAAA,CACrB5B,CAAAA,GACF,CAAA,KAAA,GAAWQ,EAAO,IAAA,GAAS,uBAAA,CAAyB,CAElD,IAAMqB,CAAAA,CAAcxD,EAAO,SAAA,CACxB0B,CAAAA,EACCA,CAAAA,CAAE,IAAA,GAAS,YACXA,CAAAA,CAAE,YAAA,EAAc,UAAA,GAAeS,CAAAA,CAAO,WAC1C,CAAA,CACIqB,CAAAA,EAAe,CAAA,EAAKxD,CAAAA,CAAOwD,CAAW,CAAA,CAAE,YAAA,EAC1CxD,EAAOwD,CAAW,CAAA,CAAE,aAAc,YAAA,CAAa,IAAA,CAAK,CAClD,IAAA,CAAMrB,EAAO,OAAA,CAAU,MAAA,CAAS,QAAA,CAChC,OAAA,CAASA,EAAO,KAAA,EAAS,EAAA,CACzB,QAAA,CAAUA,CAAAA,CAAO,UACjB,YAAA,CAAc,kBAChB,CAA8B,CAAA,CAEhCR,CAAAA,GACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,IAAA,GAAS,0BAAA,CAA4B,CAErD,IAAMqB,CAAAA,CAAcxD,CAAAA,CAAO,SAAA,CACxB0B,GACCA,CAAAA,CAAE,IAAA,GAAS,UAAA,EACXA,CAAAA,CAAE,cAAc,UAAA,GAAeS,CAAAA,CAAO,WAC1C,CAAA,CACIqB,CAAAA,EAAe,GAAKxD,CAAAA,CAAOwD,CAAW,CAAA,CAAE,YAAA,GAC1CxD,EAAOwD,CAAW,CAAA,CAAE,YAAA,CAAc,MAAA,CAAS,YAC3CxD,CAAAA,CAAOwD,CAAW,CAAA,CAAE,YAAA,CAAc,OAASrB,CAAAA,CAAO,MAAA,CAClDnC,CAAAA,CAAOwD,CAAW,EAAE,YAAA,CAAc,UAAA,CAChCrB,CAAAA,CAAO,WAAA,CAAA,CAEXR,IACF,CAAA,KAAA,GACEQ,CAAAA,CAAO,IAAA,GAAS,mBAChBA,CAAAA,CAAO,IAAA,GAAS,oBAAA,CAChB,CAEA,IAAMsB,CAAAA,CAAsC,CAC1C,UAAWtB,CAAAA,CAAO,WAAA,CAClB,SAAUA,CAAAA,CAAO,SAAA,CACjB,eAAA,CAAiBA,CAAAA,CAAO,iBACxB,SAAA,CAAWA,CAAAA,CAAO,UAAA,CAClB,MAAA,CACEA,EAAO,IAAA,GAAS,iBAAA,CACZ,SAAA,CACAA,CAAAA,CAAO,SACL,OAAA,CACA,WAAA,CACR,QAASA,CAAAA,CAAO,OAAA,CAChB,QAASA,CAAAA,CAAO,QAAA,CAChB,UAAA,CAAYA,CAAAA,CAAO,WACrB,CAAA,CACMG,CAAAA,CAActC,CAAAA,CAAO,SAAA,CACxB0B,GAAMA,CAAAA,CAAE,cAAA,EAAgB,SAAA,GAAcS,CAAAA,CAAO,WAChD,CAAA,CACIG,CAAAA,EAAe,EACjBtC,CAAAA,CAAOsC,CAAW,EAAE,cAAA,CAAiBmB,CAAAA,CAErCzD,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,MAAA,CACN,OAAA,CAASmC,CAAAA,CAAO,SAAW,EAAA,CAC3B,SAAA,CAAWA,CAAAA,CAAO,WAAA,CAClB,SAAUA,CAAAA,CAAO,SAAA,CACjB,gBAAiBA,CAAAA,CAAO,gBAAA,CACxB,OACEsB,CAAAA,CAAe,MAAA,GAAW,SAAA,CAAY,SAAA,CAAY,YACpD,cAAA,CAAAA,CAAAA,CACA,YAAA,CAAc,kBAChB,CAAqB,CAAA,CAEvB9B,CAAAA,GACF,CAAA,KAAA,GAAWQ,EAAO,IAAA,GAAS,sBAAA,CAAwB,CAEjDZ,CAAAA,EAAc,CAEd,IAAMmC,CAAAA,CAAuC,CAC3C,QAAA,CAAUvB,CAAAA,CAAO,UAAY,EAAA,CAC7B,OAAA,CAASA,CAAAA,CAAO,OAAA,EAAW,EAAC,CAC5B,OAAA,CAASA,CAAAA,CAAO,OAAA,CAChB,cAAeA,CAAAA,CAAO,eAAA,GAAoB,GAC1C,SAAA,CAAWA,CAAAA,CAAO,WAClB,kBAAA,CAAoBA,CAAAA,CAAO,mBAAA,CAC3B,YAAA,CAAcA,EAAO,aAAA,CACrB,YAAA,CAAcA,CAAAA,CAAO,aACvB,EAGAnC,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,uBACN,OAAA,CAAS0D,CAAAA,CAAkB,SAC3B,iBAAA,CAAAA,CAAAA,CACA,UAAWvB,CAAAA,CAAO,UACpB,CAAC,CAAA,CAEDjC,EAAuBwD,CAAAA,CAGlB5D,CAAAA,GACHA,CAAAA,CAAmB4D,CAAAA,CAAkB,UAGvC/B,CAAAA,GACF,CAAA,KAAA,GAAWQ,CAAAA,CAAO,OAAS,oBAAA,CAAsB,CAC/CZ,GAAc,CACdpB,EAAAA,CAAmB,GAEnB,IAAMwD,CAAAA,CACJxB,CAAAA,CAAO,OAAA,EAAS,cAAgBrC,CAAAA,CAC5B8D,CAAAA,CAAUzB,CAAAA,CAAO,OAAA,EAAS,GAC1B0B,CAAAA,CAAU1B,CAAAA,CAAO,OAAA,EAAS,QAAA,EAAU,QAEpC2B,CAAAA,CAAAA,CAAkB,IAAA,CAAK,KAAI,CAAIjE,CAAAA,EAAmB,IACxDF,CAAAA,CAAU,UAAA,CACRI,CAAAA,CACA4D,CAAAA,CACAC,EACA5D,CAAAA,CACAC,CAAAA,CACA4D,CAAAA,CACA3D,CAAAA,CACA4D,CACF,CAAA,CACAhE,CAAAA,CAAmB6D,CAAAA,CACfC,CAAAA,GAAS7D,EAAiB6D,CAAAA,CAAAA,CAC9B,KACF,SACEzB,CAAAA,CAAO,IAAA,GAAS,0BAChBA,CAAAA,CAAO,UAAA,EACPxC,CAAAA,CAAU,gBAAA,CAGVA,EAAU,gBAAA,CAAiBwC,CAAAA,CAAO,UAAU,CAAA,CAAA,KACvC,IAAIA,CAAAA,CAAO,IAAA,GAAS,OAAA,CACzB,MAAM,IAAI,KAAA,CAAMA,CAAAA,CAAO,OAAS,cAAc,CAAA,CACzC,GAAIA,CAAAA,CAAO,IAAA,GAAS,MAAA,CAAQ,CAGjC,GAAIpC,CAAAA,EAAkB,CAACI,EAAAA,CAAkB,CACvCoB,GAAc,CACd,IAAMwC,CAAAA,CAAAA,CAAsB,IAAA,CAAK,KAAI,CAAIlE,CAAAA,EAAmB,IAC5DF,CAAAA,CAAU,UAAA,CACRI,EACAD,CAAAA,EAAoB,EAAA,CACpBqC,CAAAA,CAAO,UAAA,CACPnC,EACAC,CAAAA,CACA,KAAA,CAAA,CACAC,CAAAA,CACA6D,CACF,EACF,CAAA,KAAW5B,CAAAA,CAAO,UAAA,EAAcpC,CAAAA,EAC9BJ,EAAU,eAAA,CAAgB,CACxB,GAAII,CAAAA,CACJ,WAAA,CAAa,EACf,CAAC,CAAA,CAECoC,CAAAA,CAAO,UAAA,GAAYpC,EAAiBoC,CAAAA,CAAO,UAAA,CAAA,CAC/C,KACF,CAAA,CACF,OAAS,CAAA,CAAG,CAEV,GAAI,CAAA,YAAa,OAAS,CAAA,CAAE,OAAA,GAAY,iBAGpC,CAAA,CAAE,OAAA,CAAQ,WAAW,cAAc,CAAA,EACnC,CAAA,CAAE,OAAA,CAAQ,WAAW,YAAY,CAAA,CAAA,CAEjC,MAAM,CAIZ,CACF,CACF,CAEA,OAAO,CAAE,eAAApC,CAAAA,CAAgB,gBAAA,CAAAD,CAAiB,CAC5C,CAMO,SAASkE,EAAAA,CAAejI,CAAAA,CAA8C,CAC3E,GAAM,CAACkI,CAAAA,CAAUC,CAAW,CAAA,CAAIC,QAAAA,CAA4B,EAAE,CAAA,CACxD,CAACC,CAAAA,CAAaC,CAAc,CAAA,CAAIF,QAAAA,CAAS,KAAK,CAAA,CAC9C,CAACG,CAAAA,CAAoBC,CAAqB,CAAA,CAAIJ,QAAAA,CAClD,IACF,CAAA,CACM,CAAC1H,GAAAA,CAAS+H,CAAU,EAAIL,QAAAA,CAA8B,IAAI,CAAA,CAC1D,CAACM,EAASC,CAAU,CAAA,CAAIP,SAAS,IAAI,CAAA,CACrC,CAACQ,EAAAA,CAAOC,CAAQ,CAAA,CAAIT,QAAAA,CAAwB,IAAI,CAAA,CAEhDU,CAAAA,CAAYC,MAAAA,CAAO/I,CAAM,EAC/B8I,CAAAA,CAAU,OAAA,CAAU9I,CAAAA,CAIpB,IAAMgJ,EAAaD,MAAAA,CAAOrI,GAAO,EACjCsI,CAAAA,CAAW,OAAA,CAAUtI,IACrB,IAAMuI,CAAAA,CAAiBF,MAAAA,CAAOV,CAAW,EACzCY,CAAAA,CAAe,OAAA,CAAUZ,CAAAA,CAEzB,IAAMa,EAAkBH,MAAAA,CAAO,IAAI,GAA0B,CAAA,CACvDI,EAAqBJ,MAAAA,CACzB,IAAI,GACN,CAAA,CAIAK,SAAAA,CAAU,IAAM,CACd,IAAIC,CAAAA,CAAY,KAAA,CAEhB,eAAeC,CAAAA,EAAO,CACpB,GAAI,CACF,IAAMC,CAAAA,CAAO,MAAMnJ,EAAAA,CAAY0I,CAAAA,CAAU,OAAO,CAAA,CAC3CO,CAAAA,GACHZ,EAAWc,CAAI,CAAA,CACfZ,EAAW,CAAA,CAAK,CAAA,EAEpB,CAAA,MAASa,CAAAA,CAAK,CACPH,CAAAA,GACHR,CAAAA,CACEW,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,sBACvC,CAAA,CACAb,CAAAA,CAAW,KAAK,CAAA,EAEpB,CACF,CAEA,OAAAW,CAAAA,GACO,IAAM,CACXD,CAAAA,CAAY,KACd,CACF,CAAA,CAAG,CAACrJ,CAAAA,CAAO,SAAA,CAAWA,EAAO,WAAW,CAAC,CAAA,CAGzC,IAAMuF,EAAWkE,OAAAA,CAAQ,IAAMlG,GAAmB7C,GAAO,CAAA,CAAG,CAACA,GAAO,CAAC,CAAA,CAC/DgJ,CAAAA,CAAkBC,EAAmBpE,CAAQ,CAAA,CAG7CqE,CAAAA,CAAyBb,MAAAA,CAAO,IAAI,GAA4C,CAAA,CAGhFhI,CAAAA,CAAa8I,WAAAA,CACjB,MAAO7I,CAAAA,EAAgC,CACrC,IAAM8I,CAAAA,CAAiBd,CAAAA,CAAW,QAClC,GAAI,CAACc,CAAAA,CAAgB,MAAM,IAAI,KAAA,CAAM,iBAAiB,CAAA,CACtD,IAAM3I,EAAe,MAAMJ,EAAAA,CAAoB+H,CAAAA,CAAU,OAAA,CAASgB,EAAgB9I,CAAI,CAAA,CACtF,OAAA4I,CAAAA,CAAuB,OAAA,CAAQ,IAAIzI,CAAAA,CAAc,CAC/C,EAAA,CAAIA,CAAAA,CACJ,SAAUH,CAAAA,CAAK,IAAA,CACf,QAAA,CAAUA,CAAAA,CAAK,KACf,IAAA,CAAMA,CAAAA,CAAK,IAAA,CACX,OAAA,CAASA,EAAK,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,CACtC,OAAA,CAASA,EAAK,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,CACtC,WAAY,CAACA,CAAAA,CAAK,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,EAAK,CAACA,CAAAA,CAAK,IAAA,CAAK,WAAW,QAAQ,CAC/E,CAAC,CAAA,CACMG,CACT,EACA,EACF,CAAA,CAGM4I,CAAAA,CAA2BF,YAAa1I,CAAAA,EAAyB,CACrEyI,CAAAA,CAAuB,OAAA,CAAQ,OAAOzI,CAAY,EACpD,CAAA,CAAG,EAAE,CAAA,CAIC6I,CAAAA,CAAuBH,YAC3B,MAAOI,CAAAA,EAAwD,CAC7D,IAAMH,CAAAA,CAAiBd,CAAAA,CAAW,OAAA,CAClC,GAAI,CAACc,CAAAA,CAAgB,MAAM,IAAI,MAAM,iBAAiB,CAAA,CAEtD,GAAM,CAAE,cAAAI,CAAAA,CAAe,SAAA,CAAAC,EAAW,UAAA,CAAAC,CAAW,EAAIH,CAAAA,CACjD,OAAA,CAAQ,GAAA,CAAI,CAAA,qCAAA,EAAwCE,CAAS,CAAA,OAAA,EAAUD,CAAa,CAAA,CAAA,CAAG,CAAA,CACvF,IAAMG,CAAAA,CAAUnB,CAAAA,CAAgB,OAAA,CAAQ,GAAA,CAAIiB,CAAS,CAAA,CAErD,GAAI,CAACE,CAAAA,CAEH,OAAO,OAGT,GAAI,CACF,IAAM1J,CAAAA,CAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,CAChC0J,CAAAA,CAAQD,CAAU,CAAA,CAClB,IAAI,OAAA,CAAQ,CAACE,EAAGC,CAAAA,GACd,UAAA,CACE,IAAMA,CAAAA,CAAO,IAAI,MAAM,8BAA8B,CAAC,CAAA,CACtD,GACF,CACF,CACF,CAAC,CAAA,CAED,OAAA,OAAA,CAAQ,IAAI,CAAA,gBAAA,EAAmBJ,CAAS,CAAA,6BAAA,EAAgCD,CAAa,GAAG,CAAA,CACxF,MAAM5I,EAAewH,CAAAA,CAAU,OAAA,CAASgB,EAAgB,CACtD,aAAA,CAAAI,CAAAA,CACA,MAAA,CAAAvJ,CACF,CAAC,CAAA,CACD,OAAA,CAAQ,GAAA,CAAI,mCAAmCwJ,CAAS,CAAA,OAAA,EAAUD,CAAa,CAAA,CAAA,CAAG,EAC3E,CAAA,CACT,CAAA,MAAStB,CAAAA,CAAO,CACd,eAAQ,KAAA,CACN,CAAA,gBAAA,EAAmBuB,CAAS,CAAA,mBAAA,CAAA,CAC5BvB,CACF,CAAA,CACA,MAAMtH,CAAAA,CAAewH,CAAAA,CAAU,QAASgB,CAAAA,CAAgB,CACtD,aAAA,CAAAI,CAAAA,CACA,MAAOtB,CAAAA,YAAiB,KAAA,CAAQA,EAAM,OAAA,CAAU,MAAA,CAAOA,CAAK,CAC9D,CAAC,CAAA,CACM,IACT,CACF,CAAA,CACA,EACF,CAAA,CAGAQ,UAAU,IAAM,CACd,GAAI,CAAC1I,IAAS,OAEd,IAAMoJ,EAAiBpJ,GAAAA,CAEnB8J,CAAAA,CAAuB,KACvBC,CAAAA,CAAwD,IAAA,CACxDC,CAAAA,CAAuD,IAAA,CACvDC,EAAmB,CAAA,CACnBC,CAAAA,CAAW,KAAA,CAEf,SAASC,GAAU,CACjB,GAAID,CAAAA,CAAU,OAEd,IAAMvH,CAAAA,CAAMD,EAAAA,CAAkB0F,EAAU,OAAA,CAASgB,CAAc,EAC/DU,CAAAA,CAAK,IAAI,SAAA,CAAUnH,CAAG,EAEtBmH,CAAAA,CAAG,MAAA,CAAS,IAAM,CAChB,QAAQ,GAAA,CAAI,+BAA+B,CAAA,CAC3CG,CAAAA,CAAmB,EAGnBF,CAAAA,CAAiB,WAAA,CAAY,IAAM,CAC7BD,CAAAA,EAAI,aAAe,SAAA,CAAU,IAAA,EAC/BA,CAAAA,CAAG,IAAA,CAAK,KAAK,SAAA,CAAU,CAAE,IAAA,CAAM,WAAY,CAAC,CAAC,EAEjD,CAAA,CAAGvH,EAAqB,EAC1B,CAAA,CAEAuH,CAAAA,CAAG,UAAaM,CAAAA,EAAU,CACxB,GAAI,CACF,IAAMtK,CAAAA,CAAO,IAAA,CAAK,MAAMsK,CAAAA,CAAM,IAAI,CAAA,CAC9BtK,CAAAA,CAAK,OAAS,wBAAA,EAA4BA,CAAAA,CAAK,UAAA,EACjDwJ,CAAAA,CAAqBxJ,EAAK,UAAU,CAAA,CAAE,KAAK,MAAOuK,CAAAA,EAAY,CAC5D,GAAI,CAACA,CAAAA,CAAS,CACZ,IAAMC,CAAAA,CAAWlC,CAAAA,CAAU,OAAA,CAAQ,wBAAA,CACXkC,GAAW,MAAMA,CAAAA,CAASxK,CAAAA,CAAK,UAAU,GAG/Dc,CAAAA,CAAewH,CAAAA,CAAU,QAASgB,CAAAA,CAAgB,CAChD,cAAetJ,CAAAA,CAAK,UAAA,CAAW,aAAA,CAC/B,KAAA,CAAO,8BAA8BA,CAAAA,CAAK,UAAA,CAAW,SAAS,CAAA,CAAA,CAChE,CAAC,CAAA,CAAE,KAAA,CAAM,OAAA,CAAQ,KAAK,EAE1B,CACF,CAAC,EAAE,KAAA,CAAM,OAAA,CAAQ,KAAK,EAE1B,CAAA,KAAQ,CAER,CACF,EAEAgK,CAAAA,CAAG,OAAA,CAAU,IAAM,CAMjB,GALIC,CAAAA,GACF,aAAA,CAAcA,CAAc,CAAA,CAC5BA,EAAiB,IAAA,CAAA,CAGf,CAACG,EAAU,CACb,IAAMK,EAAQ,IAAA,CAAK,GAAA,CACjB/H,EAAAA,CAA0B,IAAA,CAAK,IAAI,CAAA,CAAGyH,CAAgB,CAAA,CACtDxH,EACF,EACAwH,CAAAA,EAAAA,CACA,OAAA,CAAQ,GAAA,CAAI,CAAA,4CAAA,EAA+CM,CAAK,CAAA,EAAA,CAAI,CAAA,CACpEP,EAAiB,UAAA,CAAWG,CAAAA,CAASI,CAAK,EAC5C,CACF,CAAA,CAEAT,CAAAA,CAAG,QAAWhB,CAAAA,EAAQ,CACpB,OAAA,CAAQ,KAAA,CAAM,6BAA8BA,CAAG,EACjD,EACF,CAEA,OAAAqB,CAAAA,EAAQ,CAED,IAAM,CACXD,CAAAA,CAAW,KACPH,CAAAA,EAAgB,aAAA,CAAcA,CAAc,CAAA,CAC5CC,GAAgB,YAAA,CAAaA,CAAc,CAAA,CAC3CF,CAAAA,GACFA,EAAG,OAAA,CAAU,IAAA,CACbA,CAAAA,CAAG,KAAA,IAEP,CACF,CAAA,CAAG,CAAC9J,GAAAA,CAASsJ,CAAoB,CAAC,CAAA,CAGlC,IAAM5I,CAAAA,CAAkByI,WAAAA,CACtB,MAAOiB,CAAAA,EAAsC,CAC3C,IAAMhB,CAAAA,CAAiBd,EAAW,OAAA,CAClC,GAAI,CAACc,CAAAA,CAAgB,MAAM,IAAI,KAAA,CAAM,iBAAiB,CAAA,CACtD,MAAM1I,GAAyB0H,CAAAA,CAAU,OAAA,CAASgB,CAAAA,CAAgBgB,CAAK,EACzE,CAAA,CACA,EACF,CAAA,CAIMI,EAAcrB,WAAAA,CAClB,MAAOsB,CAAAA,CAAiBC,CAAAA,GAA6B,CACnD,IAAMtB,CAAAA,CAAiBd,EAAW,OAAA,CAC5BqC,CAAAA,CAAU,CAAC,CAACF,CAAAA,CAAQ,IAAA,EAAK,CACzBG,EAAiBF,CAAAA,EAAiBA,CAAAA,CAAc,MAAA,CAAS,CAAA,CAE/D,GAAK,CAACC,CAAAA,EAAW,CAACC,CAAAA,EAAmBrC,EAAe,OAAA,EAAW,CAACa,EAAgB,OAEhF,IAAMnG,EAAe,CAAA,IAAA,EAAO,IAAA,CAAK,GAAA,EAAK,GAEhC4H,CAAAA,CAAqBH,CAAAA,EACvB,GAAA,CAAKI,CAAAA,EAAO5B,EAAuB,OAAA,CAAQ,GAAA,CAAI4B,CAAE,CAAC,EACnD,MAAA,CAAO,OAAO,CAAA,CAEXC,CAAAA,CAA+B,CACnC,EAAA,CAAI9H,CAAAA,CACJ,WAAA,CAAawH,CAAAA,CACb,YAAa,CACX,EAAA,CAAI,MAAA,CACJ,IAAA,CAAMrC,EAAU,OAAA,CAAQ,QAAA,EAAY,KAAA,CACpC,IAAA,CAAM,MACR,CAAA,CACA,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,aAAY,CAClC,WAAA,CAAayC,CAAAA,EAAoB,MAAA,CAASA,EAAqB,MACjE,CAAA,CAGAH,CAAAA,EAAe,OAAA,CAASI,GAAO5B,CAAAA,CAAuB,OAAA,CAAQ,MAAA,CAAO4B,CAAE,CAAC,CAAA,CAGxE,IAAME,EAAyB,CAAA,kBAAA,EAAqB,IAAA,CAAK,KAAK,CAAA,CAAA,CACxDC,CAAAA,CAAwC,CAC5C,GAAID,CAAAA,CACJ,WAAA,CAAa,EAAA,CACb,WAAA,CAAa,CACX,EAAA,CAAI,WAAA,CACJ,IAAA,CACE5B,CAAAA,CAAe,OAAO,QAAA,EAAU,WAAA,EAChCA,EAAe,MAAA,CAAO,cAAA,CACxB,KAAM,WAAA,CACN,SAAA,CAAWA,CAAAA,CAAe,MAAA,CAAO,UAAU,gBAC7C,CAAA,CACA,SAAA,CAAW,IAAI,MAAK,CAAE,WAAA,EAAY,CAClC,WAAA,CAAa,IACf,CAAA,CAEA3B,CAAAA,CAAayD,GAAS,CAAC,GAAGA,EAAMH,CAAAA,CAAaE,CAAoB,CAAC,CAAA,CAClErD,EAAe,IAAI,CAAA,CACnBE,CAAAA,CAAsBkD,CAAsB,EAG5C5C,CAAAA,CAAU,OAAA,CAAQ,oBAAA,GAAuB,CAAE,GAAInF,CAAAA,CAAc,OAAA,CAAAwH,CAAQ,CAAC,CAAA,CAEtE,GAAI,CACF,IAAM9K,CAAAA,CAAiBN,CAAAA,CAAkB+I,EAAU,OAAO,CAAA,CAEpDxI,CAAAA,CAAW,MAAM,MACrB,CAAA,EAAGD,CAAc,CAAA,0BAAA,CAAA,CACjB,CACE,OAAQ,MAAA,CACR,OAAA,CAAS,CACP,cAAA,CAAgB,kBAAA,CAChB,cAAe,CAAA,OAAA,EAAUyJ,CAAAA,CAAe,KAAK,CAAA,CAAA,CAC7C,gBAAiB7J,CAAAA,EACnB,CAAA,CACA,IAAA,CAAM,KAAK,SAAA,CAAU,CACnB,SAAA,CAAW6J,CAAAA,CAAe,OAAO,SAAA,CACjC,YAAA,CAAcqB,EACd,UAAA,CAAYxH,CAAAA,CACZ,SAAU,EAAC,CACX,cAAA,CAAgByH,CAAAA,EAAiB,EACnC,CAAC,CACH,CACF,EAEA,GAAI,CAAC9K,CAAAA,CAAS,EAAA,CACZ,MAAM,IAAI,KAAA,CAAM,eAAeA,CAAAA,CAAS,MAAM,EAAE,CAAA,CAGlD,IAAMoD,CAAAA,CAASpD,CAAAA,CAAS,MAAM,SAAA,EAAU,CACxC,GAAI,CAACoD,EAAQ,MAAM,IAAI,KAAA,CAAM,kBAAkB,EAE/C,IAAM/C,CAAAA,CAAS,MAAM8C,EAAAA,CACnBC,CAAAA,CACAoG,EACAnG,CAAAA,CACA,CACE,eAAA,CAAkBkI,CAAAA,EAAQ,CACxBrD,CAAAA,CAAsBqD,CAAAA,CAAI,EAAE,CAAA,CAE5B1D,EAAayD,CAAAA,EAIJ,CAAC,GAHSA,CAAAA,CAAK,OACnBE,CAAAA,EAAMA,CAAAA,CAAE,KAAOJ,CAClB,CAAA,CACqBG,CAAG,CACzB,EACH,CAAA,CACA,eAAA,CAAkBE,GAAW,CAC3B5D,CAAAA,CAAayD,CAAAA,EACXA,CAAAA,CAAK,IAAKC,CAAAA,EACRA,CAAAA,CAAI,EAAA,GAAOE,CAAAA,CAAO,GAAK,CAAE,GAAGF,EAAK,GAAGE,CAAO,EAAIF,CACjD,CACF,EACF,CAAA,CACA,sBAAuB,CAACG,CAAAA,CAAOC,CAAAA,GAAU,CACvC9D,EAAayD,CAAAA,EACXA,CAAAA,CAAK,GAAA,CAAKC,CAAAA,EACRA,EAAI,EAAA,GAAOG,CAAAA,CAAQ,CAAE,GAAGH,CAAAA,CAAK,GAAII,CAAM,CAAA,CAAIJ,CAC7C,CACF,EACF,CAAA,CACA,UAAA,CAAY,CACV7H,CAAAA,CACA4D,EACAC,CAAAA,CACA5D,CAAAA,CACAC,EAAAA,CACA4D,EAAAA,CACA3D,GACA+H,EAAAA,GACG,CACClI,GACFmE,CAAAA,CAAayD,EAAAA,EACXA,GAAK,GAAA,CAAKC,EAAAA,EACRA,EAAAA,CAAI,EAAA,GAAO7H,EACP,CACE,GAAG6H,EAAAA,CACH,EAAA,CAAIhE,GAAWgE,EAAAA,CAAI,EAAA,CACnB,WAAA,CAAajE,CAAAA,CACb,YAAa,CAAA,CAAA,CACb,SAAA,CAAW3D,EACX,gBAAA,CAAAC,EAAAA,CACA,UAAW4D,EAAAA,CACX,oBAAA,CAAA3D,EAAAA,CACA,aAAA,CAAA+H,EACF,CAAA,CACAL,EACN,CACF,CAAA,CAIF/C,EAAU,OAAA,CAAQ,0BAAA,GAA6B,CAC7C,EAAA,CAAIjB,GAAW7D,CAAAA,EAAkB,EAAA,CACjC,QAAS4D,CACX,CAAC,EACH,CAAA,CACA,gBAAA,CAAkB,MAAOqC,CAAAA,EAAe,CAEtC,GAAI,CADY,MAAMD,CAAAA,CAAqBC,CAAU,CAAA,CACvC,CACZ,IAAMe,CAAAA,CAAWlC,EAAU,OAAA,CAAQ,wBAAA,CAEnC,GAAI,EADoBkC,EAAW,MAAMA,CAAAA,CAASf,CAAU,CAAA,CAAI,IAC1C,CACpB,IAAMV,EAAAA,CAAOP,CAAAA,CAAW,QACpBO,EAAAA,EACF,MAAMjI,CAAAA,CAAewH,CAAAA,CAAU,QAASS,EAAAA,CAAM,CAC5C,cAAeU,CAAAA,CAAW,aAAA,CAC1B,MAAO,CAAA,2BAAA,EAA8BA,CAAAA,CAAW,SAAS,CAAA,CAAA,CAC3D,CAAC,EAEL,CACF,CACF,CACF,CACF,CAAA,CAGItJ,CAAAA,CAAO,cAAA,EACTwH,CAAAA,CAAayD,GACXA,CAAAA,CAAK,GAAA,CAAKC,GACRA,CAAAA,CAAI,EAAA,GAAOlL,EAAO,cAAA,CACd,CAAE,GAAGkL,CAAAA,CAAK,YAAa,CAAA,CAAM,CAAA,CAC7BA,CACN,CACF,EAEJ,CAAA,MAASrC,CAAAA,CAAK,CACZ,OAAA,CAAQ,MAAM,uBAAA,CAAyBA,CAAG,EAE1C,IAAMD,CAAAA,CAAOP,EAAW,OAAA,CAClBmD,CAAAA,CAA4B,CAChC,EAAA,CAAI,SAAS,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CACvB,YAAa,kDAAA,CACb,WAAA,CAAa,CACX,EAAA,CAAI,YACJ,IAAA,CACE5C,CAAAA,EAAM,OAAO,QAAA,EAAU,WAAA,EACvBA,GAAM,MAAA,CAAO,cAAA,EAAkB,WAAA,CACjC,IAAA,CAAM,YACN,SAAA,CAAWA,CAAAA,EAAM,MAAA,CAAO,QAAA,EAAU,gBACpC,CAAA,CACA,SAAA,CAAW,IAAI,IAAA,GAAO,WAAA,EACxB,EAEApB,CAAAA,CAAayD,CAAAA,EAAS,CACpB,GAAGA,CAAAA,CAAK,MAAA,CAAQE,CAAAA,EAAMA,EAAE,EAAA,GAAOJ,CAAsB,CAAA,CACrDS,CACF,CAAC,CAAA,CACDtD,CAAAA,CAASW,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,aAAa,EAC7D,CAAA,OAAE,CACAlB,EAAe,KAAK,CAAA,CACpBE,CAAAA,CAAsB,IAAI,EAC5B,CACF,CAAA,CACA,CAACwB,CAAoB,CACvB,CAAA,CAGMoC,CAAAA,CAAiBvC,WAAAA,CAAY,SAA6B,CAC9D,IAAMC,CAAAA,CAAiBd,EAAW,OAAA,CAClC,GAAI,CAACc,CAAAA,CAAgB,MAAM,IAAI,KAAA,CAAM,iBAAiB,CAAA,CAEtD,IAAMnJ,CAAAA,CAAS,MAAMF,GAAaqI,CAAAA,CAAU,OAAA,CAASgB,CAAc,CAAA,CAC9DnJ,EAAO,KAAA,EACV,OAAA,CAAQ,KAAK,2FAAsF,CAAA,CAErG,IAAM0L,CAAAA,CAA+B,CACnC,GAAGvC,CAAAA,CACH,OAAQ,CAAE,GAAGA,CAAAA,CAAe,MAAA,CAAQ,UAAWnJ,CAAAA,CAAO,QAAS,CAAA,CAC/D,KAAA,CAAOA,EAAO,KAAA,EAASmJ,CAAAA,CAAe,KACxC,CAAA,CAWA,GALAd,EAAW,OAAA,CAAUqD,CAAAA,CACrB5D,CAAAA,CAAW4D,CAAc,EACzBlE,CAAAA,CAAY,EAAE,CAAA,CAGVgB,EAAmB,OAAA,CAAQ,IAAA,CAAO,CAAA,CAAG,CACvC,QAAQ,GAAA,CAAI,CAAA,yBAAA,EAA4BA,EAAmB,OAAA,CAAQ,IAAI,sBAAsB,CAAA,CAC7F,GAAI,CACF,MAAM3H,EACJsH,CAAAA,CAAU,OAAA,CACVuD,CAAAA,CACA,KAAA,CAAM,KAAKlD,CAAAA,CAAmB,OAAA,CAAQ,MAAA,EAAQ,CAChD,EACF,CAAA,MAASK,EAAK,CACZ,OAAA,CAAQ,KAAK,wCAAA,CAA0CA,CAAG,EAC5D,CACF,CAEA,OAAO7I,CAAAA,CAAO,QAChB,CAAA,CAAG,EAAE,CAAA,CAGC2L,CAAAA,CAAezC,WAAAA,CACnB,MAAO9H,CAAAA,EAA8C,CACnD,IAAM+H,CAAAA,CAAiBd,CAAAA,CAAW,QAClC,GAAI,CAACc,CAAAA,CAAgB,MAAM,IAAI,KAAA,CAAM,iBAAiB,CAAA,CAEtDhI,EAAAA,CAAuBC,CAAI,CAAA,CAE3BmH,CAAAA,CAAgB,OAAA,CAAQ,GAAA,CAAInH,EAAK,IAAA,CAAMA,CAAAA,CAAK,OAAO,CAAA,CACnD,IAAMwK,EAAavJ,EAAAA,CAAwBjB,CAAI,CAAA,CAC/CoH,CAAAA,CAAmB,QAAQ,GAAA,CAAIpH,CAAAA,CAAK,IAAA,CAAMwK,CAAU,EAEpD,GAAI,CACF,MAAM/K,CAAAA,CAAuBsH,EAAU,OAAA,CAASgB,CAAAA,CAAgB,CAACyC,CAAU,CAAC,EAC5E,OAAA,CAAQ,GAAA,CAAI,CAAA,4BAAA,EAA+BxK,CAAAA,CAAK,IAAI,CAAA,CAAA,CAAG,EACzD,CAAA,MAASyH,CAAAA,CAAK,CACZ,MAAAN,CAAAA,CAAgB,OAAA,CAAQ,MAAA,CAAOnH,EAAK,IAAI,CAAA,CACxCoH,EAAmB,OAAA,CAAQ,MAAA,CAAOpH,EAAK,IAAI,CAAA,CACrCyH,CACR,CACF,EACA,EACF,CAAA,CAKMgD,EAAAA,CAAgB3C,YACpB,MAAO4C,CAAAA,EAAiD,CACtD,IAAM3C,EAAiBd,CAAAA,CAAW,OAAA,CAClC,GAAI,CAACc,EAAgB,MAAM,IAAI,KAAA,CAAM,iBAAiB,EAGtD,IAAA,IAAW/H,CAAAA,IAAQ0K,CAAAA,CACjB3K,EAAAA,CAAuBC,CAAI,CAAA,CAI7B,IAAM2K,CAAAA,CAAmB,IAAI,IAAIxD,CAAAA,CAAgB,OAAO,EAClDyD,CAAAA,CAAsB,IAAI,IAAIxD,CAAAA,CAAmB,OAAO,CAAA,CAExDyD,CAAAA,CAAgE,EAAC,CACvE,IAAA,IAAW7K,CAAAA,IAAQ0K,CAAAA,CAAO,CACxBvD,CAAAA,CAAgB,OAAA,CAAQ,GAAA,CAAInH,CAAAA,CAAK,KAAMA,CAAAA,CAAK,OAAO,EACnD,IAAMwK,CAAAA,CAAavJ,GAAwBjB,CAAI,CAAA,CAC/CoH,CAAAA,CAAmB,OAAA,CAAQ,IAAIpH,CAAAA,CAAK,IAAA,CAAMwK,CAAU,CAAA,CACpDK,EAAgB,IAAA,CAAKL,CAAU,EACjC,CAEA,GAAI,CAEF,MAAM/K,EAAuBsH,CAAAA,CAAU,OAAA,CAASgB,EAAgB8C,CAAe,CAAA,CAC/E,IAAMC,CAAAA,CAAYJ,EAAM,GAAA,CAAIK,CAAAA,EAAKA,CAAAA,CAAE,IAAI,EACvC,OAAA,CAAQ,GAAA,CAAI,CAAA,4BAAA,EAA+B,IAAA,CAAK,UAAUD,CAAS,CAAC,KAAKJ,CAAAA,CAAM,MAAM,SAAS,EAChG,CAAA,MAASjD,CAAAA,CAAK,CAEZ,MAAAN,CAAAA,CAAgB,OAAA,CAAUwD,CAAAA,CAC1BvD,CAAAA,CAAmB,QAAUwD,CAAAA,CACvBnD,CACR,CACF,CAAA,CACA,EACF,CAAA,CAGMuD,EAA8BtD,OAAAA,CAClC,IACEvB,EAAS,GAAA,CAAK2D,CAAAA,GAAS,CACrB,EAAA,CAAIA,EAAI,EAAA,CACR,WAAA,CAAaA,CAAAA,CAAI,WAAA,EAAa,QAAQ,iBAAA,CAAmB,EAAE,CAAA,EAAKA,CAAAA,CAAI,YACpE,WAAA,CAAaA,CAAAA,CAAI,YACjB,SAAA,CAAWA,CAAAA,CAAI,UACf,WAAA,CAAaA,CAAAA,CAAI,WAAA,CACjB,SAAA,CAAWA,EAAI,SAAA,CACf,gBAAA,CAAkBA,CAAAA,CAAI,gBAAA,CACtB,UAAWA,CAAAA,CAAI,SAAA,CACf,WAAA,CAAaA,CAAAA,CAAI,YACjB,oBAAA,CAAsBA,CAAAA,CAAI,qBAC1B,aAAA,CAAeA,CAAAA,CAAI,aACrB,CAAA,CAAE,CAAA,CACJ,CAAC3D,CAAQ,CACX,CAAA,CAGM8E,EAAAA,CAAgBnD,WAAAA,CAAaoD,CAAAA,EAA6B,CAC9DxE,CAAAA,CAAWwE,CAAU,EACvB,CAAA,CAAG,EAAE,CAAA,CAEL,OAAO,CACL,QAAA,CAAUF,EACV,WAAA,CAAA1E,CAAAA,CACA,kBAAA,CAAAE,CAAAA,CACA,YAAA2C,CAAAA,CACA,UAAA,CAAAnK,CAAAA,CACA,wBAAA,CAAAgJ,EACA,OAAA,CAAArJ,GAAAA,CACA,OAAA,CAAAgI,CAAAA,CACA,MAAAE,EAAAA,CACA,QAAA,CAAArD,EACA,eAAA,CAAAmE,CAAAA,CACA,eAAA0C,CAAAA,CACA,YAAA,CAAAE,CAAAA,CACA,aAAA,CAAAE,GACA,eAAA,CAAApL,CAAAA,CACA,oBAAA,CAAA4I,CAAAA,CACA,cAAAgD,EACF,CACF,CCltDO,SAASE,GAAiBC,CAAAA,CAA8B,CAC7D,GAAI,CACF,IAAMC,EAAQD,CAAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAC7B,GAAIC,CAAAA,CAAM,MAAA,GAAW,CAAA,CAAG,OAAO,KAE/B,IAAMC,CAAAA,CAASD,CAAAA,CAAM,CAAC,EAAE,OAAA,CAAQ,IAAA,CAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAM,GAAG,CAAA,CACtDE,CAAAA,CAAc,IAAA,CAAKD,CAAM,CAAA,CACzBE,CAAAA,CAAU,IAAA,CAAK,KAAA,CAAMD,CAAW,CAAA,CAEtC,OAAI,OAAOC,CAAAA,CAAQ,KAAQ,QAAA,CAClBA,CAAAA,CAAQ,IAAM,GAAA,CAGhB,IACT,MAAQ,CACN,OAAO,IACT,CACF,CAKO,SAASC,EAAAA,CACdL,CAAAA,CACAM,CAAAA,CACS,CACT,IAAMC,CAAAA,CAASR,EAAAA,CAAiBC,CAAK,EACrC,OAAIO,CAAAA,GAAW,KAAa,IAAA,CACrBA,CAAAA,CAAS,KAAK,GAAA,EAAI,EAAKD,CAChC,CAKO,SAASE,EAAAA,CAAeR,CAAAA,CAAwB,CACrD,IAAMO,EAASR,EAAAA,CAAiBC,CAAK,CAAA,CACrC,OAAIO,IAAW,IAAA,CAAa,IAAA,CACrB,KAAK,GAAA,EAAI,EAAKA,CACvB,CAKO,SAASE,EAAAA,CAAmBT,CAAAA,CAAuB,CACxD,IAAMO,CAAAA,CAASR,EAAAA,CAAiBC,CAAK,EACrC,OAAIO,CAAAA,GAAW,IAAA,CAAa,CAAA,CACrB,KAAK,GAAA,CAAI,CAAA,CAAGA,EAAS,IAAA,CAAK,GAAA,EAAK,CACxC","file":"index.js","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"]}
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.js","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 reconnectTimer = setTimeout(connect, delay);\n }\n };\n\n ws.onerror = () => {\n // Intentionally silent — onerror always precedes onclose,\n // which handles reconnection with exponential backoff.\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"]}