@8wave/ai-elements 0.119.0-beta.27 → 0.119.0-beta.31

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.
Files changed (136) hide show
  1. package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js → PkChatbotFilePreview-DiuzVVKH.js} +2 -2
  2. package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js.map → PkChatbotFilePreview-DiuzVVKH.js.map} +1 -1
  3. package/dist/_chunks/{PkStreamingMarkdown-BK9O_NLx.js → PkStreamingMarkdown-DKyHYHUN.js} +3 -3
  4. package/dist/_chunks/{PkStreamingMarkdown-BK9O_NLx.js.map → PkStreamingMarkdown-DKyHYHUN.js.map} +1 -1
  5. package/dist/_chunks/{PkToolEditSpreadsheet-D-RCfnrN.js → PkToolEditSpreadsheet-CfJ3BWMe.js} +2 -2
  6. package/dist/_chunks/{PkToolEditSpreadsheet-D-RCfnrN.js.map → PkToolEditSpreadsheet-CfJ3BWMe.js.map} +1 -1
  7. package/dist/_chunks/{PkToolRequestOAuthConnection-QYDJPUFF.js → PkToolRequestOAuthConnection-klmrRZWz.js} +2 -2
  8. package/dist/_chunks/{PkToolRequestOAuthConnection-QYDJPUFF.js.map → PkToolRequestOAuthConnection-klmrRZWz.js.map} +1 -1
  9. package/dist/_chunks/{PkToolShowArtifact-DGUj8f1k.js → PkToolShowArtifact-ChDm6ZEK.js} +2 -2
  10. package/dist/_chunks/{PkToolShowArtifact-DGUj8f1k.js.map → PkToolShowArtifact-ChDm6ZEK.js.map} +1 -1
  11. package/dist/_chunks/{PkToolShowCalendarEvent-BEjPZC1F.js → PkToolShowCalendarEvent-CRVtR3oP.js} +2 -2
  12. package/dist/_chunks/{PkToolShowCalendarEvent-BEjPZC1F.js.map → PkToolShowCalendarEvent-CRVtR3oP.js.map} +1 -1
  13. package/dist/_chunks/{PkToolShowContactForm-DXJI0MPZ.js → PkToolShowContactForm-CfCy-b8w.js} +3 -4
  14. package/dist/_chunks/PkToolShowContactForm-CfCy-b8w.js.map +1 -0
  15. package/dist/_chunks/{PkToolShowDiagram-C5mSqZDp.js → PkToolShowDiagram-JpRMa4Jj.js} +3 -3
  16. package/dist/_chunks/{PkToolShowDiagram-C5mSqZDp.js.map → PkToolShowDiagram-JpRMa4Jj.js.map} +1 -1
  17. package/dist/_chunks/{PkToolShowForm-UQo0Xdiq.js → PkToolShowForm-DnIwTGl4.js} +2 -2
  18. package/dist/_chunks/{PkToolShowForm-UQo0Xdiq.js.map → PkToolShowForm-DnIwTGl4.js.map} +1 -1
  19. package/dist/_chunks/{PkToolShowImageGallery-rZ3AtIEP.js → PkToolShowImageGallery-Ab8fJ9jY.js} +4 -4
  20. package/dist/_chunks/{PkToolShowImageGallery-rZ3AtIEP.js.map → PkToolShowImageGallery-Ab8fJ9jY.js.map} +1 -1
  21. package/dist/_chunks/{PkToolShowLocation-BOmxHZKd.js → PkToolShowLocation-D5d6bbP-.js} +2 -2
  22. package/dist/_chunks/{PkToolShowLocation-BOmxHZKd.js.map → PkToolShowLocation-D5d6bbP-.js.map} +1 -1
  23. package/dist/_chunks/{PkToolShowProductList-ByeSoIwq.js → PkToolShowProductList-DztzZVDd.js} +2 -2
  24. package/dist/_chunks/{PkToolShowProductList-ByeSoIwq.js.map → PkToolShowProductList-DztzZVDd.js.map} +1 -1
  25. package/dist/_chunks/{PkToolShowSources-q4XBOwJl.js → PkToolShowSources-Bvg3f3GC.js} +3 -3
  26. package/dist/_chunks/{PkToolShowSources-q4XBOwJl.js.map → PkToolShowSources-Bvg3f3GC.js.map} +1 -1
  27. package/dist/_chunks/{PkToolShowVideo-BmHHW4Ep.js → PkToolShowVideo-DdoYLl7R.js} +3 -3
  28. package/dist/_chunks/{PkToolShowVideo-BmHHW4Ep.js.map → PkToolShowVideo-DdoYLl7R.js.map} +1 -1
  29. package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js → PkToolShowWeather-CnpPZCLm.js} +2 -2
  30. package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js.map → PkToolShowWeather-CnpPZCLm.js.map} +1 -1
  31. package/dist/_chunks/{PkToolShowWebPages-BaapF0CC.js → PkToolShowWebPages-BooCEJrs.js} +3 -3
  32. package/dist/_chunks/{PkToolShowWebPages-BaapF0CC.js.map → PkToolShowWebPages-BooCEJrs.js.map} +1 -1
  33. package/dist/_chunks/{chatImagePolicy-CDNkMKdT.js → chatImagePolicy-CfJt8_9Z.js} +2 -2
  34. package/dist/_chunks/{chatImagePolicy-CDNkMKdT.js.map → chatImagePolicy-CfJt8_9Z.js.map} +1 -1
  35. package/dist/_chunks/{index.es-BrsciU25.js → index.es-oI6RqNZW.js} +2 -2
  36. package/dist/_chunks/{index.es-BrsciU25.js.map → index.es-oI6RqNZW.js.map} +1 -1
  37. package/dist/_chunks/{src-Dt4rhhPN.js → src-DL9TKN-Z.js} +2 -2
  38. package/dist/_chunks/src-DL9TKN-Z.js.map +1 -0
  39. package/dist/_chunks/{useLightbox-pPBe746W.js → useLightbox-1KKLemEE.js} +2 -2
  40. package/dist/_chunks/{useLightbox-pPBe746W.js.map → useLightbox-1KKLemEE.js.map} +1 -1
  41. package/dist/ai-elements.es.js +25 -25
  42. package/dist/ai-elements.es.js.map +1 -1
  43. package/dist-vue/PkChatbot.js +1 -1
  44. package/dist-vue/PkChatbotAudioTranscript.js +1 -1
  45. package/dist-vue/PkChatbotEmptyState.js +1 -1
  46. package/dist-vue/PkChatbotFilePreview.js +1 -1
  47. package/dist-vue/PkChatbotInput.js +1 -1
  48. package/dist-vue/PkChatbotMessages.js +1 -1
  49. package/dist-vue/PkChatbotStepPayload.js +1 -1
  50. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  51. package/dist-vue/PkChatbotSteps.js +1 -1
  52. package/dist-vue/PkChatbotViewChat.js +1 -1
  53. package/dist-vue/PkChatbotViewConversations.js +1 -1
  54. package/dist-vue/PkChatbotViewFiles.js +1 -1
  55. package/dist-vue/PkChatbotViewProfile.js +1 -1
  56. package/dist-vue/_chunks/{PkChatbot-D0BQ3VnX.js → PkChatbot-C18mnGJ9.js} +8 -8
  57. package/dist-vue/_chunks/{PkChatbot-D0BQ3VnX.js.map → PkChatbot-C18mnGJ9.js.map} +1 -1
  58. package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js → PkChatbotAudioTranscript-0rvrhSRQ.js} +2 -2
  59. package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js.map → PkChatbotAudioTranscript-0rvrhSRQ.js.map} +1 -1
  60. package/dist-vue/_chunks/{PkChatbotEmptyState-CGjFcwwB.js → PkChatbotEmptyState-BKiyP0Ga.js} +2 -2
  61. package/dist-vue/_chunks/{PkChatbotEmptyState-CGjFcwwB.js.map → PkChatbotEmptyState-BKiyP0Ga.js.map} +1 -1
  62. package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js → PkChatbotFilePreview-D5H-RIk2.js} +2 -2
  63. package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js.map → PkChatbotFilePreview-D5H-RIk2.js.map} +1 -1
  64. package/dist-vue/_chunks/{PkChatbotInput-BVBQY0V5.js → PkChatbotInput-GvgsYsUw.js} +3 -3
  65. package/dist-vue/_chunks/{PkChatbotInput-BVBQY0V5.js.map → PkChatbotInput-GvgsYsUw.js.map} +1 -1
  66. package/dist-vue/_chunks/{PkChatbotMessages-CK0lhcDj.js → PkChatbotMessages-CDLsj7qw.js} +21 -21
  67. package/dist-vue/_chunks/{PkChatbotMessages-CK0lhcDj.js.map → PkChatbotMessages-CDLsj7qw.js.map} +1 -1
  68. package/dist-vue/_chunks/{PkChatbotStepPayload-l57qHqVf.js → PkChatbotStepPayload-Dm-HCHcG.js} +2 -2
  69. package/dist-vue/_chunks/{PkChatbotStepPayload-l57qHqVf.js.map → PkChatbotStepPayload-Dm-HCHcG.js.map} +1 -1
  70. package/dist-vue/_chunks/{PkChatbotStepToolDetail-ChrOa4W4.js → PkChatbotStepToolDetail-Bpd_cZEO.js} +3 -3
  71. package/dist-vue/_chunks/{PkChatbotStepToolDetail-ChrOa4W4.js.map → PkChatbotStepToolDetail-Bpd_cZEO.js.map} +1 -1
  72. package/dist-vue/_chunks/{PkChatbotSteps-DnU9r4XT.js → PkChatbotSteps-C4qBM3_t.js} +5 -5
  73. package/dist-vue/_chunks/{PkChatbotSteps-DnU9r4XT.js.map → PkChatbotSteps-C4qBM3_t.js.map} +1 -1
  74. package/dist-vue/_chunks/{PkChatbotViewChat-DIx3nwEg.js → PkChatbotViewChat-By2TY72m.js} +8 -8
  75. package/dist-vue/_chunks/{PkChatbotViewChat-DIx3nwEg.js.map → PkChatbotViewChat-By2TY72m.js.map} +1 -1
  76. package/dist-vue/_chunks/{PkChatbotViewConversations-DDWO1Ci_.js → PkChatbotViewConversations-CU5NfEO4.js} +4 -4
  77. package/dist-vue/_chunks/{PkChatbotViewConversations-DDWO1Ci_.js.map → PkChatbotViewConversations-CU5NfEO4.js.map} +1 -1
  78. package/dist-vue/_chunks/{PkChatbotViewFiles-O9YjrGP0.js → PkChatbotViewFiles-CD-UZPT5.js} +2 -2
  79. package/dist-vue/_chunks/{PkChatbotViewFiles-O9YjrGP0.js.map → PkChatbotViewFiles-CD-UZPT5.js.map} +1 -1
  80. package/dist-vue/_chunks/{PkChatbotViewProfile-BoImMMj2.js → PkChatbotViewProfile-DPlb_Wca.js} +2 -2
  81. package/dist-vue/_chunks/{PkChatbotViewProfile-BoImMMj2.js.map → PkChatbotViewProfile-DPlb_Wca.js.map} +1 -1
  82. package/dist-vue/_chunks/{PkStreamingMarkdown-JEkbkY5k.js → PkStreamingMarkdown-CsHzdW69.js} +3 -3
  83. package/dist-vue/_chunks/{PkStreamingMarkdown-JEkbkY5k.js.map → PkStreamingMarkdown-CsHzdW69.js.map} +1 -1
  84. package/dist-vue/_chunks/{PkSvgViewer-DrA4yi8Q.js → PkSvgViewer-D6DJ2jVO.js} +2 -2
  85. package/dist-vue/_chunks/{PkSvgViewer-DrA4yi8Q.js.map → PkSvgViewer-D6DJ2jVO.js.map} +1 -1
  86. package/dist-vue/_chunks/{PkToolEditSpreadsheet-BX_h8Hut.js → PkToolEditSpreadsheet-D8Zp9gzW.js} +2 -2
  87. package/dist-vue/_chunks/{PkToolEditSpreadsheet-BX_h8Hut.js.map → PkToolEditSpreadsheet-D8Zp9gzW.js.map} +1 -1
  88. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-Bwj84qHq.js → PkToolRequestOAuthConnection-DosWR9I4.js} +2 -2
  89. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-Bwj84qHq.js.map → PkToolRequestOAuthConnection-DosWR9I4.js.map} +1 -1
  90. package/dist-vue/_chunks/{PkToolShowArtifact-BIvl5I2I.js → PkToolShowArtifact-BVofKJ7b.js} +2 -2
  91. package/dist-vue/_chunks/{PkToolShowArtifact-BIvl5I2I.js.map → PkToolShowArtifact-BVofKJ7b.js.map} +1 -1
  92. package/dist-vue/_chunks/{PkToolShowCalendarEvent-ve1I0xaV.js → PkToolShowCalendarEvent-u9O_Sl3-.js} +2 -2
  93. package/dist-vue/_chunks/{PkToolShowCalendarEvent-ve1I0xaV.js.map → PkToolShowCalendarEvent-u9O_Sl3-.js.map} +1 -1
  94. package/dist-vue/_chunks/{PkToolShowContactForm-CddxrLBZ.js → PkToolShowContactForm-BzdIFTnC.js} +3 -4
  95. package/dist-vue/_chunks/PkToolShowContactForm-BzdIFTnC.js.map +1 -0
  96. package/dist-vue/_chunks/{PkToolShowDiagram-DdR4x6pP.js → PkToolShowDiagram-CaoB4k6y.js} +4 -4
  97. package/dist-vue/_chunks/{PkToolShowDiagram-DdR4x6pP.js.map → PkToolShowDiagram-CaoB4k6y.js.map} +1 -1
  98. package/dist-vue/_chunks/{PkToolShowForm-DiXcYws_.js → PkToolShowForm-vYuaPtu0.js} +3 -3
  99. package/dist-vue/_chunks/{PkToolShowForm-DiXcYws_.js.map → PkToolShowForm-vYuaPtu0.js.map} +1 -1
  100. package/dist-vue/_chunks/{PkToolShowImageGallery-COrJEjSv.js → PkToolShowImageGallery-ooygXk7j.js} +4 -4
  101. package/dist-vue/_chunks/{PkToolShowImageGallery-COrJEjSv.js.map → PkToolShowImageGallery-ooygXk7j.js.map} +1 -1
  102. package/dist-vue/_chunks/{PkToolShowLocation-CHi_cONJ.js → PkToolShowLocation-DVMpFdRk.js} +2 -2
  103. package/dist-vue/_chunks/{PkToolShowLocation-CHi_cONJ.js.map → PkToolShowLocation-DVMpFdRk.js.map} +1 -1
  104. package/dist-vue/_chunks/{PkToolShowProductList-BIvJlpMT.js → PkToolShowProductList-D-HJ9a_h.js} +2 -2
  105. package/dist-vue/_chunks/{PkToolShowProductList-BIvJlpMT.js.map → PkToolShowProductList-D-HJ9a_h.js.map} +1 -1
  106. package/dist-vue/_chunks/{PkToolShowSources-CC-0Oh4K.js → PkToolShowSources-DJ35l3Z3.js} +3 -3
  107. package/dist-vue/_chunks/{PkToolShowSources-CC-0Oh4K.js.map → PkToolShowSources-DJ35l3Z3.js.map} +1 -1
  108. package/dist-vue/_chunks/{PkToolShowVideo-UUNkUlrg.js → PkToolShowVideo-xcg1gdIE.js} +3 -3
  109. package/dist-vue/_chunks/{PkToolShowVideo-UUNkUlrg.js.map → PkToolShowVideo-xcg1gdIE.js.map} +1 -1
  110. package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js → PkToolShowWeather-DJxKxVp_.js} +2 -2
  111. package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js.map → PkToolShowWeather-DJxKxVp_.js.map} +1 -1
  112. package/dist-vue/_chunks/{PkToolShowWebPages-CLYx_PgL.js → PkToolShowWebPages-BuaRjavD.js} +3 -3
  113. package/dist-vue/_chunks/{PkToolShowWebPages-CLYx_PgL.js.map → PkToolShowWebPages-BuaRjavD.js.map} +1 -1
  114. package/dist-vue/_chunks/{createChatbotApiClient-BdmGCAQR.js → createChatbotApiClient-G3Tt1I67.js} +2 -2
  115. package/dist-vue/_chunks/{createChatbotApiClient-BdmGCAQR.js.map → createChatbotApiClient-G3Tt1I67.js.map} +1 -1
  116. package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js → mcpOAuthReport-3A9v_gW_.js} +2 -2
  117. package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js.map → mcpOAuthReport-3A9v_gW_.js.map} +1 -1
  118. package/dist-vue/_chunks/{src-DCfvejyT.js → src-DpkuiHam.js} +2 -2
  119. package/dist-vue/_chunks/src-DpkuiHam.js.map +1 -0
  120. package/dist-vue/_chunks/{useChatbotStore-BAv5K91p.js → useChatbotStore-C1sgxgD1.js} +4 -4
  121. package/dist-vue/_chunks/{useChatbotStore-BAv5K91p.js.map → useChatbotStore-C1sgxgD1.js.map} +1 -1
  122. package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js → useSafeLocalStorage-DLIc8pkn.js} +2 -2
  123. package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js.map → useSafeLocalStorage-DLIc8pkn.js.map} +1 -1
  124. package/dist-vue/_chunks/{utils-BqPJ6DJT.js → utils-DsnEcdW3.js} +2 -2
  125. package/dist-vue/_chunks/{utils-BqPJ6DJT.js.map → utils-DsnEcdW3.js.map} +1 -1
  126. package/dist-vue/api.js +1 -1
  127. package/dist-vue/composables.js +8 -8
  128. package/dist-vue/composables.js.map +1 -1
  129. package/dist-vue/index.js +3196 -3184
  130. package/dist-vue/index.js.map +1 -1
  131. package/dist-vue/style.css +1 -1
  132. package/package.json +1 -1
  133. package/dist/_chunks/PkToolShowContactForm-DXJI0MPZ.js.map +0 -1
  134. package/dist/_chunks/src-Dt4rhhPN.js.map +0 -1
  135. package/dist-vue/_chunks/PkToolShowContactForm-CddxrLBZ.js.map +0 -1
  136. package/dist-vue/_chunks/src-DCfvejyT.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"createChatbotApiClient-BdmGCAQR.js","names":["z.object","z.coerce.date","z.enum","z.string","z.array","z.boolean","z.number","z.object","z.literal","z.string","z.url","z.record","z.unknown","z.discriminatedUnion","z.array","z.enum","z.number","z.boolean","z.coerce.date","c","l","d","f","s","n","e","t","i","r","resolveShortUrlsRequest","string","url","number","literal","array","_enum","boolean","discriminatedUnion","object","unknown","record","date","MIME_TYPE_REGEX","VoiceSessionSchema","DeviceContextSchema","resolveToolName","AgentRankingSchema","AgentReasoningSchema","AgentGatewayOptionsSchema","AgentWebSearchSchema","zodQs","AgentBuiltInTool","AgentSearchMode","UNAVAILABLE_TOOL_ERROR_PATTERN","removeTrailingSlash","addInitialSlash","AbuseCategory","\"Harassment\"","\"HateSpeech\"","\"SexualContent\"","\"SelfHarm\"","\"Violence\"","\"PromptInjection\"","\"DataExtraction\"","\"Spam\"","\"OffTopicPersistent\"","\"Impersonation\"","AbuseConfidence","\"Low\"","\"Medium\"","\"High\"","LlmIssueCategory","\"FalseSuccess\"","\"Hallucination\"","\"OffBrand\"","\"DataLeak\"","\"InappropriateTone\"","\"RefusalLoop\"","\"Repetition\"","\"FailedAction\"","\"EmptyReply\"","\"StuckFlow\"","ConversationAnalysisTrigger","\"SummaryCycle\"","\"AgentRequest\"","\"Manual\"","UserEngagement","\"Disengaged\"","UserTone","\"Polite\"","\"Neutral\"","\"Impatient\"","\"Aggressive\"","\"Abusive\"","Sentiment","\"Positive\"","\"Negative\"","\"Frustrated\"","\"Excited\"","SentimentTrend","\"Improving\"","\"Stable\"","\"Degrading\"","CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS","ConversationAnalysisSchema","TextPartSchema","FilePartSchema","MessagePartSchema","BlockedReasonCode","\"SevereAbuse\"","\"HighRiskScore\"","\"RepeatedWarnings\"","\"Web\"","\"WhatsApp\"","\"Teams\"","\"Voice\"","\"Api\"","\"Reasoning\"","\"Endpoint\"","ChatChannel","summarizeToolSelection","message","decision","groupOfKey","group","key","groupByName","used","enabled","part","toolName","names","name","groupId","selected","seeded","groups","b","a","TURN_EVALUATION_QUESTION_IDS","TOOL_TERMINAL_STATES","ChatSchema","ChatsPublicSchema","e","t","n","r","i","c$1","l$1","c","y","u","h","E","x","C","S","_","w","T","D","v","f","m","k","d","O","g","A","M","p","n$1","i$1","n$2","i$3","o","s","r$1","P","j","N","i$5","F","Audience","\"Backoffice\"","\"Frontoffice\"","\"System\"","\"Public\"","createAliasResolver","buildMongoQueryMatcher","ac","createAccessControl","defaultStatements","adminAc","ownerAc","memberAc","resolveShortUrls","root","backendUrl","response","options","ConversationSchema","parseConversation","result","raw","readErrorMessage","fallback","body","createChatbotApiClient","basePath","baseUrl","frontofficeBase","request","init","responseType","userFilter","userId","agentId","chatId","suffix","inline","documentId","payload","orgSlug","formData","file","text","title","type","bearer","`Authorization`","base","storedFileName","params","lat","lon","lang","query","context","sessionId","hashes"],"sources":["../../../../packages/models/src/schema/ConversationAnalysis.ts","../../../../packages/models/src/schema/Chat.ts","../../../../node_modules/.pnpm/@ucast+core@2.0.0/node_modules/@ucast/core/dist/esm/index.mjs","../../../../node_modules/.pnpm/@ucast+mongo@3.0.0/node_modules/@ucast/mongo/dist/esm/index.mjs","../../../../packages/ability/src/types.ts","../../../../packages/ability/src/index.ts","../../../../packages/composable/src/chatbot/api/resolveShortUrls.ts","../../../../packages/composable/src/chatbot/api/createChatbotApiClient.ts"],"sourcesContent":["import * as z from 'zod'\n\nexport enum AbuseCategory {\n Harassment = 'harassment',\n HateSpeech = 'hate_speech',\n SexualContent = 'sexual_content',\n SelfHarm = 'self_harm',\n Violence = 'violence',\n PromptInjection = 'prompt_injection',\n DataExtraction = 'data_extraction',\n Spam = 'spam',\n OffTopicPersistent = 'off_topic_persistent',\n Impersonation = 'impersonation',\n}\n\nexport enum AbuseConfidence {\n Low = 'low',\n Medium = 'medium',\n High = 'high',\n}\n\nexport enum LlmIssueCategory {\n FalseSuccess = 'false_success',\n Hallucination = 'hallucination',\n OffBrand = 'off_brand',\n DataLeak = 'data_leak',\n InappropriateTone = 'inappropriate_tone',\n RefusalLoop = 'refusal_loop',\n Repetition = 'repetition',\n FailedAction = 'failed_action',\n EmptyReply = 'empty_reply',\n StuckFlow = 'stuck_flow',\n}\n\nexport enum ConversationAnalysisTrigger {\n SummaryCycle = 'summary_cycle',\n AgentRequest = 'agent_request',\n Manual = 'manual',\n}\n\nexport enum UserEngagement {\n High = 'high',\n Medium = 'medium',\n Low = 'low',\n Disengaged = 'disengaged',\n}\n\nexport enum UserTone {\n Polite = 'polite',\n Neutral = 'neutral',\n Impatient = 'impatient',\n Aggressive = 'aggressive',\n Abusive = 'abusive',\n}\n\nexport enum Sentiment {\n Positive = 'positive',\n Neutral = 'neutral',\n Negative = 'negative',\n Frustrated = 'frustrated',\n Excited = 'excited',\n}\n\nexport enum SentimentTrend {\n Improving = 'improving',\n Stable = 'stable',\n Degrading = 'degrading',\n}\n\n/** Longest abuse or LLM issue summary an analysis stores. */\nexport const CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS = 1000\n\nexport const ConversationAnalysisSchema = z.object({\n // --- Metadata (set programmatically, not by the LLM) ---\n analyzedAt: z.coerce.date().describe('When the analysis was generated.'),\n analysisTrigger: z\n .enum(ConversationAnalysisTrigger)\n .describe('What triggered this analysis run.'),\n\n // --- Sentiment & Tone ---\n sentiment: z\n .enum(Sentiment)\n .describe('Overall user sentiment in the conversation.'),\n sentimentTrend: z\n .enum(SentimentTrend)\n .describe('How the user sentiment evolved during the conversation.'),\n userTone: z\n .enum(UserTone)\n .describe('Predominant tone of the user messages.'),\n\n // --- Language ---\n language: z\n .string()\n .max(10)\n .describe(\n 'ISO 639-1 language code of the conversation (e.g. \"en\", \"it\").',\n ),\n\n // --- Topics ---\n topics: z\n .array(z.string().max(100))\n .max(10)\n .describe('Main topics discussed, as short lowercase labels.'),\n\n // --- User Abuse Detection ---\n userAbuseDetected: z\n .boolean()\n .describe(\n 'Whether user abuse was detected. If false, userAbuseCategories MUST be empty.',\n ),\n userAbuseCategories: z\n .array(z.enum(AbuseCategory))\n .default([])\n .describe(\n 'Abuse categories detected. Non-empty only if userAbuseDetected is true.',\n ),\n userAbuseConfidence: z\n .enum(AbuseConfidence)\n .optional()\n .describe(\n 'Confidence level of the abuse detection. Set only if userAbuseDetected is true.',\n ),\n userAbuseSummary: z\n .string()\n .max(CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS)\n .optional()\n .describe(\n 'Brief description of the abusive behavior detected. Always write in English. Set only if userAbuseDetected is true.',\n ),\n\n // --- LLM Quality Issues ---\n llmIssueDetected: z\n .boolean()\n .describe(\n 'Whether an LLM quality issue was detected. If false, llmIssueCategories MUST be empty.',\n ),\n llmIssueCategories: z\n .array(z.enum(LlmIssueCategory))\n .default([])\n .describe(\n 'LLM issue categories detected. Non-empty only if llmIssueDetected is true.',\n ),\n llmIssueSummary: z\n .string()\n .max(CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS)\n .optional()\n .describe(\n 'Brief description of the LLM quality issue detected. Always write in English. Set only if llmIssueDetected is true.',\n ),\n\n // --- Engagement ---\n userEngagement: z\n .enum(UserEngagement)\n .describe('Level of user engagement in the conversation.'),\n conversationGoalMet: z\n .boolean()\n .optional()\n .describe(\n 'Whether the user seems to have achieved what they came for. Leave undefined if unclear.',\n ),\n\n // --- Risk Score ---\n riskScore: z\n .number()\n .int()\n .min(0)\n .max(100)\n .describe(\n 'Overall risk score (0 = safe, 100 = critical). Combination of abuse severity, persistence and escalation.',\n ),\n})\n\nexport type ConversationAnalysis = z.infer<typeof ConversationAnalysisSchema>\n","import * as z from 'zod'\nimport { resolveToolName, zodQs } from '../utils'\nimport type { UIMessage, LanguageModelUsage } from 'ai'\nimport { ConversationAnalysisSchema } from './ConversationAnalysis'\nimport {\n AgentBuiltInTool,\n ENABLE_TOOLS_TOOL,\n AgentGatewayOptionsSchema,\n AgentReasoningSchema,\n AgentWebSearchSchema,\n AgentSearchMode,\n AgentRankingSchema,\n} from './Agent'\nimport { MIME_TYPE_REGEX } from './Media'\nimport type { PlatformContext } from './Platform'\nimport { UNAVAILABLE_TOOL_ERROR_PATTERN } from './StreamError'\n\nimport { DeviceContextSchema, type DeviceContext } from './DeviceContext'\n\nexport { DeviceContextSchema, type DeviceContext }\n\nconst TextPartSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n})\n\nconst FilePartSchema = z.object({\n type: z.literal('file'),\n mediaType: z.string().regex(MIME_TYPE_REGEX),\n url: z.url(),\n filename: z.string().optional(),\n providerMetadata: z\n .record(z.string(), z.record(z.string(), z.unknown()))\n .optional(),\n})\n\nconst MessagePartSchema = z.discriminatedUnion('type', [\n TextPartSchema,\n FilePartSchema,\n])\n\nexport const ChatRequestSchema = z.object({\n id: z.string(),\n messages: z.array(\n z.object({\n id: z.string().optional(),\n role: z.enum(['assistant', 'user']),\n content: z.string(),\n parts: z.array(MessagePartSchema),\n createdAt: z.string().optional(),\n }),\n ),\n model: z.string().optional(),\n temperature: z.number().optional(),\n prompt: z.string().optional(),\n maxOutputTokens: z.number().positive().optional(),\n presencePenalty: z.number().min(-2).max(2).optional(),\n frequencyPenalty: z.number().min(-2).max(2).optional(),\n searchMode: z.enum(AgentSearchMode).optional(),\n limit: z.number().optional(),\n ranking: AgentRankingSchema.optional(),\n reasoning: AgentReasoningSchema,\n webSearch: AgentWebSearchSchema.optional(),\n maxStepCount: z.number().int().min(1).max(40).optional(),\n disabledTools: z.array(z.enum(AgentBuiltInTool)).optional(),\n fallbackModels: z.array(z.string()).optional(),\n gatewayOptions: AgentGatewayOptionsSchema.partial().optional(),\n deviceContext: DeviceContextSchema.optional(),\n externalContext: z.record(z.string(), z.unknown()).optional(),\n smoothStream: z.boolean().optional(),\n})\n\nexport type ChatRequest = z.infer<typeof ChatRequestSchema>\n\n/**\n * What the chat route validates on the way in.\n *\n * Deliberately not `ChatRequestSchema`: a turn resumed after a client tool or\n * a tool approval posts the assistant message back, whose parts are tool\n * calls, and the part union above accepts text and files only. Pinning the\n * body to it would answer 400 to a legitimate resume. So this validates the\n * envelope the turn cannot run without and lets the rest through untouched\n * (`loose`), which is also why the overrides the client sends still reach the\n * service.\n *\n * The id is minted by the client and read back as a row key: without it the\n * lookup ran with `undefined` and the route answered 500 instead of 400\n * (found 2026-09-21).\n */\nexport const ChatRequestEnvelopeSchema = z\n .object({\n id: z.string().min(1),\n messages: z.array(z.object({ role: z.string() }).loose()).min(1),\n })\n .loose()\n\nexport enum BlockedReasonCode {\n SevereAbuse = 'severe_abuse',\n HighRiskScore = 'high_risk_score',\n RepeatedWarnings = 'repeated_warnings',\n}\n\nexport type ChatMetadata = {\n ipAddress: string\n /** HTTP `Origin` of the request, empty for a server-to-server caller. */\n origin: string\n userAgent: string\n /**\n * Non-default transport the conversation arrived through (for example\n * `openai-api`), so cost and usage reports can isolate it. Absent for the\n * web and widget chat.\n */\n transport?: string\n}\n\n/**\n * Channel a conversation arrived through, as the analytics slice it.\n *\n * Derived at read time and never stored: a platform conversation is identified\n * by `chats.metadata.platform` ({@link PlatformType}), every other non-web\n * surface by `chats.metadata.transport` ({@link ChatTransport}), and a chat\n * carrying neither marker is the web chat or the widget (the historical\n * default, which is why those rows have nothing to read). `reasoning_chats`\n * and `agent_endpoint_logs` have no metadata at all, so each of those tables\n * is a channel by itself.\n *\n * Not to be confused with {@link AgentChannel}, which says where an agent is\n * published (frontoffice, app, widget): this says where a conversation came\n * from.\n *\n * Only the platforms we actually run are listed. `PlatformType` declares five\n * more, and one of those appearing in the data is reported under its own raw\n * value rather than folded into a bucket, so a channel nobody expected shows\n * up in the dashboard instead of hiding inside `other`.\n */\nexport enum ChatChannel {\n /** Web chat and embeddable widget: no marker on the row. */\n Web = 'web',\n WhatsApp = 'whatsapp',\n Teams = 'teams',\n /** Spoken session opened by us, `transport = voice`. */\n Voice = 'voice',\n /** OpenAI-compatible REST surface, `transport = openai-api`. */\n Api = 'api',\n /** Every row of `reasoning_chats`: the reasoning endpoint. */\n Reasoning = 'reasoning',\n /** Every row of `agent_endpoint_logs`: the custom agent endpoints. */\n Endpoint = 'endpoint',\n}\n\nexport const ChatChannelSchema = z.enum(ChatChannel)\n\nexport type ChatMessageActions =\n 'show-info' | 'revise' | 'regenerate' | 'upvote' | 'downvote' | 'feedback'\n\nexport type Chat = z.infer<typeof ChatSchema>\nexport type ChatsQuerystring = z.infer<typeof ChatsQuerystringSchema>\n\nexport type UIChatMessageDeviceContext = DeviceContext\n\n/** Kinds of tool group the working set decides on, one group per MCP server. */\nexport type ToolGroupKind = 'mcp' | 'api' | 'subagent'\n\n/**\n * What the working set decided for a turn (spec tool-catalogue-working-set,\n * F4). Group ids are those of {@link ToolCatalogueRecord}; the groups the model\n * enabled later in the turn are read from its `enableTools` calls.\n */\nexport type ToolWorkingSetRecord = {\n /** `shadow` recorded the decision and exposed everything, `active` applied it. */\n mode: 'shadow' | 'active'\n /** Groups exposed from the first step: the judged ones and the seed. */\n selected: string[]\n /** Groups the conversation seeded, exposed whatever the judgment. */\n seeded: string[]\n /** Probability the evaluation model gave each judged group, two decimals. */\n probabilities: Record<string, number>\n latencyMs: number\n /**\n * Time the evaluation was given: short in active mode, where the turn\n * waits for it, longer in shadow mode, where it runs alongside.\n */\n budgetMs: number\n /** Probability from which a judged group is exposed. */\n threshold: number\n /**\n * What the evaluation cost in USD, the amount charged to the organization.\n * Absent when it failed: nothing is charged then.\n */\n cost?: number\n inputTokens?: number\n /**\n * The evaluation answered with an error or not within the budget, and\n * every group stayed exposed.\n */\n failed?: boolean\n}\n\n/**\n * The part of a turn's tool catalogue the working set acts on (spec\n * tool-catalogue-working-set, F2): which MCP servers, API tools and sub-agents\n * were eligible, identified by id and not by the public keys, which collide\n * across servers. Enough to make a measurement repeatable without storing the\n * schemas.\n */\nexport type ToolCatalogueRecord = {\n /** Short hash of the eligible keys and their groups: two turns with the same set agree on it. */\n fingerprint: string\n groups: Array<{\n id: string\n kind: ToolGroupKind\n name: string\n /**\n * Keys of the group offered this turn: what attributes a call in the\n * message to its group, since a key names a different server's tool\n * in another turn.\n */\n keys: string[]\n }>\n workingSet?: ToolWorkingSetRecord\n}\n\n/** One group of a turn's catalogue, read against what the turn did with it. */\nexport type ToolSelectionGroup = {\n id: string\n kind: ToolGroupKind\n name: string\n tools: number\n /** Absent when the evaluation failed. */\n probability?: number\n /** Exposed from the first step in active mode, or would have been in shadow mode. */\n selected: boolean\n seeded: boolean\n /**\n * Brought back during the turn, by `enableTools` or by a direct call to\n * one of its tools that the model was refused as unavailable.\n */\n enabled: boolean\n /**\n * The model called one of its tools, whatever came of the call (an error,\n * a denied approval): the turn needed the group.\n */\n used: boolean\n}\n\nexport type ToolSelectionSummary = {\n decision: ToolWorkingSetRecord\n /** Most probable first, then by name. */\n groups: ToolSelectionGroup[]\n /**\n * Groups the turn used that the decision left out. In active mode the\n * model had to bring each one back, in shadow mode it would have had to:\n * the working set's miss, the figure F3 of the spec counts.\n */\n missed: number\n}\n\ntype SummarizedPart = {\n type: string\n toolName?: string\n state?: string\n input?: unknown\n errorText?: string\n}\n\n/**\n * The working set's decision on a turn next to what the turn did: which\n * groups it exposed, which the model brought back and which it used. Read\n * from the stored answer, whose metadata carries the record and whose parts\n * carry the calls, the way the backend read them during the turn: a call\n * counts under the name the repair would give it, and an `enableTools` call\n * only once it ran. Undefined when the working set did not decide.\n */\nexport function summarizeToolSelection(message: {\n parts?: ReadonlyArray<unknown>\n metadata?: { toolCatalogue?: ToolCatalogueRecord }\n}): ToolSelectionSummary | undefined {\n const record = message.metadata?.toolCatalogue\n const decision = record?.workingSet\n if (!record || !decision) {\n return undefined\n }\n const groupOfKey = new Map(\n record.groups.flatMap((group) =>\n group.keys.map((key) => [key, group.id] as const),\n ),\n )\n const groupByName = new Map(\n record.groups.map((group) => [group.name, group.id] as const),\n )\n const used = new Set<string>()\n const enabled = new Set<string>()\n for (const part of (message.parts ?? []) as SummarizedPart[]) {\n const toolName =\n part.type === 'dynamic-tool'\n ? part.toolName\n : part.type.startsWith('tool-')\n ? part.type.slice(5)\n : undefined\n if (!toolName) {\n continue\n }\n if (toolName === ENABLE_TOOLS_TOOL) {\n // A call whose input failed validation enabled nothing.\n const names =\n part.state === 'output-available'\n ? (part.input as { groups?: unknown })?.groups\n : undefined\n for (const name of Array.isArray(names) ? names : []) {\n const groupId = groupByName.get(String(name))\n if (groupId) {\n enabled.add(groupId)\n }\n }\n continue\n }\n const key = resolveToolName(toolName, groupOfKey.keys())\n const groupId = key && groupOfKey.get(key)\n if (!groupId) {\n continue\n }\n // A call to a hidden tool is refused as unavailable, and that refusal\n // is how the model asked for its group back.\n if (\n part.state === 'output-error' &&\n UNAVAILABLE_TOOL_ERROR_PATTERN.test(part.errorText ?? '')\n ) {\n enabled.add(groupId)\n } else {\n used.add(groupId)\n }\n }\n const selected = new Set(decision.selected)\n const seeded = new Set(decision.seeded)\n const groups = record.groups\n .map((group) => ({\n id: group.id,\n kind: group.kind,\n name: group.name,\n tools: group.keys.length,\n probability: decision.probabilities[group.id],\n selected: selected.has(group.id),\n seeded: seeded.has(group.id),\n enabled: enabled.has(group.id),\n used: used.has(group.id),\n }))\n .sort(\n (a, b) =>\n (b.probability ?? -1) - (a.probability ?? -1) ||\n a.name.localeCompare(b.name),\n )\n return {\n decision,\n groups,\n missed: groups.filter((group) => group.used && !group.selected).length,\n }\n}\n\nexport type UIChatMessageMetadata = {\n /** Unix timestamp (ms) when the stream started */\n createdAt?: number\n /** Unix timestamp (ms) when the stream finished */\n completedAt?: number\n /** Canonical model ID used for the request (e.g. `google/gemini-3-flash`) */\n model?: string\n /** Total tokens consumed across all steps */\n totalTokens?: number\n /** Per-tool-call durations in ms, keyed by tool call ID */\n partTimings?: Record<string, number>\n /** Client device context sent with the request */\n deviceContext?: UIChatMessageDeviceContext\n /** Platform channel context (WhatsApp/Teams), the device-context equivalent for platform turns */\n platformContext?: PlatformContext\n /** External context provided by the host application and validated server-side */\n externalContext?: Record<string, unknown>\n /** Provider that ultimately served the request (e.g. `vertex`, `openai`) */\n resolvedProvider?: string\n /** Actual model ID as exposed by the resolved provider (e.g. `gemini-3-flash-preview`) */\n resolvedModelId?: string\n /** Market cost of the request in USD, as a numeric string */\n cost?: string\n /** Number of model-level routing attempts made by the gateway */\n modelAttemptCount?: number\n /** Total number of provider-level attempts (includes retries across providers) */\n totalProviderAttemptCount?: number\n /** Whether Zero Data Retention was active for this request */\n zeroDataRetention?: boolean\n /** Whether the provider was instructed not to use the prompt for model training */\n disallowPromptTraining?: boolean\n /** Vercel AI Gateway generation ID, useful for tracing in the Vercel dashboard */\n generationId?: string\n /** Tokens served from the provider's prompt cache (e.g. Gemini context caching) */\n cachedTokens?: number\n /** Provider traffic tier (e.g. `PROVISIONED_THROUGHPUT`, `ON_DEMAND`) */\n trafficType?: string\n /**\n * Transport the message travelled through ({@link ChatTransport}), when it\n * was not the web chat itself: `voice` marks a spoken exchange (the user\n * text is the call transcription, the assistant text was read aloud),\n * `openai-api` an API turn. Absent on plain web messages.\n */\n transport?: string\n /**\n * The MCP servers, API tools and sub-agents this turn could use, and the\n * working set's decision on them. Absent when the agent has none. Kept\n * from a public reader: streamed only to the organization's own audiences\n * (on the closing finish), and removed from whatever else leaves the\n * organization ({@link withoutToolCatalogue}).\n */\n toolCatalogue?: ToolCatalogueRecord\n /**\n * The evaluation of the turn after the reply (spec post-turn-evaluation):\n * a probability per question. Written after the answer, and removed from\n * a public read ({@link withoutTurnEvaluation}).\n */\n turnEvaluation?: TurnEvaluationRecord\n /**\n * Set on the user message a wakeup injected (spec agent-wakeup): its text\n * is the prompt the agent left for itself, not words the user typed.\n */\n wakeup?: UIChatMessageWakeup\n}\n\n/** The wakeup a seed message belongs to (spec agent-wakeup). */\nexport type UIChatMessageWakeup = {\n id: string\n loopId: string\n iteration: number\n reason: string\n}\n\n/**\n * The questions of the post-turn evaluation, in the order they are asked and\n * listed. The backend's questions are typed against it, so the two cannot\n * drift. A reader orders by this list and not by the record: jsonb keeps the\n * keys of an object sorted by length, not in the order they were written.\n */\nexport const TURN_EVALUATION_QUESTION_IDS = [\n 'durableFact',\n 'abusive',\n 'manipulation',\n 'asksHuman',\n 'missingInfo',\n 'informationGap',\n] as const\n\nexport type TurnEvaluationQuestionId =\n (typeof TURN_EVALUATION_QUESTION_IDS)[number]\n\n/**\n * The evaluation model's answers on a finished turn (spec\n * post-turn-evaluation, F1). Recorded in shadow only: nothing reads it yet.\n */\nexport type TurnEvaluationRecord = {\n /**\n * The wording of the questions: a threshold holds only for the wording\n * it was measured on, so a record says which one it answered.\n */\n version: number\n mode: 'shadow'\n /** Probability per question, two decimals. Empty when the request failed. */\n probabilities: Record<string, number>\n latencyMs: number\n budgetMs: number\n /** Market cost of the request in USD. */\n cost?: number\n inputTokens?: number\n /** The request failed or ran past its budget: no answer was recorded. */\n failed?: true\n}\n\nexport type UIChatMessage = UIMessage & {\n metadata?: UIChatMessageMetadata\n}\n\n/**\n * The history without the turn evaluations, for a public read: a probability\n * of abuse on a user must not reach the widget. Kept apart from\n * {@link withoutToolCatalogue}, which the data export uses too, because\n * whether the export includes this judgment is still to be decided.\n */\nexport function withoutTurnEvaluation(\n messages: UIChatMessage[],\n): UIChatMessage[] {\n return messages.map((message) => {\n if (!message.metadata?.turnEvaluation) {\n return message\n }\n const { turnEvaluation: _turnEvaluation, ...metadata } =\n message.metadata\n return { ...message, metadata }\n })\n}\n\n/**\n * The history without the tool catalogue records, for a reader outside the\n * organization (a public chat read, the data export): a record names every\n * group the agent has, used or not.\n */\nexport function withoutToolCatalogue(\n messages: UIChatMessage[],\n): UIChatMessage[] {\n return messages.map((message) => {\n if (!message.metadata?.toolCatalogue) {\n return message\n }\n const { toolCatalogue: _toolCatalogue, ...metadata } = message.metadata\n return { ...message, metadata }\n })\n}\n\n/**\n * States in which a tool invocation part waits for nothing more.\n *\n * Two readers, one meaning: the backend leaves such a part alone instead of\n * forcing it to a terminal state (`completeUnresolvedToolInvocations`), and the\n * web client counts it as answered when deciding whether to resume a suspended\n * turn (`sendAutomaticallyWhen` in `useChatbotStore`). They used to keep a copy\n * each, with different membership.\n */\nexport const TOOL_TERMINAL_STATES: ReadonlySet<string> = new Set([\n 'output-available',\n 'output-error',\n 'output-denied',\n])\n\nexport const ChatSchema = z.object({\n id: z.string(),\n messages: z.array(z.unknown()) as unknown as z.ZodType<UIChatMessage[]>,\n title: z.string().nullable(),\n summary: z.string().nullable(),\n messageCountAtLastSummary: z.string().nullable(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n metadata: z.record(z.string(), z.unknown()),\n totalCostInUSD: z.string(),\n usage: z.unknown() as unknown as z.ZodType<LanguageModelUsage>,\n agentId: z.string().nullable(),\n userId: z.string(),\n organizationId: z.string(),\n deleted: z.boolean(),\n deletedAt: z.coerce.date().nullable(),\n deletedBy: z.string().nullable(),\n conversationAnalysis: ConversationAnalysisSchema.nullable().optional(),\n blocked: z.boolean(),\n blockedAt: z.coerce.date().nullable(),\n blockedReasonCode: z.enum(BlockedReasonCode).nullable(),\n blockedReason: z.string().nullable(),\n warningCount: z.number(),\n lastMessageAt: z.coerce.date(),\n})\n\nexport const ChatsQuerystringSchema = z.object({\n ...zodQs.pagination(),\n ...zodQs.sort(['updatedAt', 'createdAt', 'lastMessageAt']),\n ...zodQs.filters(['agentId', 'userId']),\n ...zodQs.range('updatedAt'),\n ...zodQs.range('lastMessageAt'),\n ...zodQs.ids(),\n startDate: z.string().optional(),\n endDate: z.string().optional(),\n})\n\nexport const ChatsPublicSchema = z.object({\n id: z.string(),\n agentId: z.string().optional(),\n organizationId: z.string(),\n summary: z.string().optional(),\n title: z.string().optional(),\n userId: z.string(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n lastMessageAt: z.coerce.date(),\n messages: z.array(z.unknown()),\n blocked: z.boolean(),\n})\n\nexport type ChatPublic = z.infer<typeof ChatsPublicSchema>\n","var e=class{constructor(e,t){this.operator=e,this.value=t,Object.defineProperty(this,`_notes`,{writable:!0})}get notes(){return this._notes}addNote(e){this._notes=this._notes||[],this._notes.push(e)}},t=class extends e{},n=class extends t{constructor(e,t){if(!Array.isArray(t))throw Error(`\"${e}\" operator expects to receive an array of conditions`);super(e,t)}};const r=`__itself__`;var i=class extends e{constructor(e,t,n){super(e,n),this.field=t}};const a=new t(`__null__`,null),o=Object.hasOwn||((e,t)=>Object.prototype.hasOwnProperty.call(e,t));function s(e,t){return t instanceof n&&t.operator===e}function c(e,t){let r;for(let i=0,a=t.length;i<a;i++){let a=t[i];if(a instanceof n){if(a.operator!==e){r&&r.push(a);continue}if(a.value.length===0)continue;r||(r=t.slice(0,i));let n=a.value;for(let e=0,t=n.length;e<t;e++)r.push(n[e])}else r&&r.push(a)}return r||t}function l(e,t){if(t.length===1)return t[0];if(t.length===0)return new n(e,t);let r=c(e,t);return r.length===1?r[0]:(r.length,new n(e,r))}const u=e=>e,d=()=>Object.create(null),f=Object.defineProperty(d(),`__@type@__`,{value:`ignore value`});function p(e,t,n=!1){if(!e||e&&e.constructor!==Object)return!1;for(let r in e)if(o(e,r)&&o(t,r)&&(!n||e[r]!==f))return!0;return!1}function m(e){let t=[];for(let n in e)o(e,n)&&e[n]!==f&&t.push(n);return t}function h(e,t){t!==a&&e.push(t)}const g=e=>l(`and`,e),_=e=>l(`or`,e);function v(e,t){let n=e[t];if(typeof n!=`function`)throw Error(`Unable to interpret \"${String(t)}\" condition. Did you forget to register interpreter for it?`);return n}function y(e){return e.operator}function b(e,t){let n=t,r=n&&n.getInterpreterName||y,i;switch(n?n.numberOfArguments:0){case 1:i=(t=>v(e,r(t,n))(t,a));break;case 3:i=((t,i,o)=>v(e,r(t,n))(t,i,o,a));break;default:i=((t,i)=>v(e,r(t,n))(t,i,a));break}let a={...n,interpret:i};return a.interpret}const x={compound(e,t,r){let i=(Array.isArray(t)?t:[t]).map(e=>r.parse(e));return new n(e.name,i)},field(e,t,n){return new i(e.name,n.field,t)},document(e,n){return new t(e.name,n)}};var S=class{constructor(e,t=d()){this.parse=this.parse.bind(this),this._options={operatorToConditionName:t.operatorToConditionName||u,defaultOperatorName:t.defaultOperatorName||`eq`,mergeFinalConditions:t.mergeFinalConditions||g},this._instructions=Object.keys(e).reduce((t,n)=>(t[n]={name:this._options.operatorToConditionName(n),...e[n]},t),{}),this._fieldInstructionContext={...t.fieldContext,field:``,query:{},parse:this.parse,hasOperators:e=>p(e,this._instructions,t.useIgnoreValue)},this._documentInstructionContext={...t.documentContext,parse:this.parse,query:{}},this._objectKeys=t.useIgnoreValue?m:Object.keys}setParse(e){this.parse=e,this._fieldInstructionContext.parse=e,this._documentInstructionContext.parse=e}parseField(e,t,n,r){let i=this._instructions[t];if(!i)throw Error(`Unsupported operator \"${t}\"`);if(i.type!==`field`)throw Error(`Unexpected ${i.type} operator \"${t}\" at field level`);return this._fieldInstructionContext.field=e,this._fieldInstructionContext.query=r,this.parseInstruction(i,n,this._fieldInstructionContext)}parseInstruction(e,t,n){return typeof e.validate==`function`&&e.validate(e,t),(e.parse||x[e.type])(e,t,n)}parseFieldOperators(e,t){let n=[],r=this._objectKeys(t);for(let i=0,a=r.length;i<a;i++){let a=r[i];if(!this._instructions[a])throw Error(`Field query for \"${e}\" may contain only operators or a plain object as a value`);h(n,this.parseField(e,a,t[a],t))}return n}parse(e){let t=[],n=this._objectKeys(e);this._documentInstructionContext.query=e;for(let r=0,i=n.length;r<i;r++){let i=n[r],a=e[i],o=this._instructions[i];if(o){if(o.type!==`document`&&o.type!==`compound`)throw Error(`Cannot use parsing instruction for operator \"${i}\" in \"document\" context as it is supposed to be used in \"${o.type}\" context`);h(t,this.parseInstruction(o,a,this._documentInstructionContext))}else this._fieldInstructionContext.hasOperators(a)?t.push(...this.parseFieldOperators(i,a)):h(t,this.parseField(i,this._options.defaultOperatorName,a,e))}return this._options.mergeFinalConditions(t)}};function C(e,t){return(n,...r)=>{let i=e(n,...r),a=t.bind(null,i);return Object.defineProperty(a,`ast`,{value:i}),a}}export{n as CompoundCondition,e as Condition,t as DocumentCondition,i as FieldCondition,r as ITSELF,a as NULL_CONDITION,S as ObjectQueryParser,g as buildAnd,_ as buildOr,b as createInterpreter,C as createTranslatorFactory,x as defaultInstructionParsers,p as hasOperators,u as identity,f as ignoreValue,s as isCompound,d as object,l as optimizedCompoundCondition};\n//# sourceMappingURL=index.mjs.map","import{CompoundCondition as e,FieldCondition as t,ITSELF as n,NULL_CONDITION as r,ObjectQueryParser as i,buildAnd as a,defaultInstructionParsers as o,optimizedCompoundCondition as s}from\"@ucast/core\";var c=Object.defineProperty,l=((e,t)=>{let n={};for(var r in e)c(n,r,{get:e[r],enumerable:!0});return t||c(n,Symbol.toStringTag,{value:`Module`}),n})({$all:()=>y,$and:()=>u,$elemMatch:()=>h,$eq:()=>E,$exists:()=>x,$gt:()=>C,$gte:()=>S,$in:()=>_,$lt:()=>w,$lte:()=>T,$mod:()=>b,$ne:()=>D,$nin:()=>v,$nor:()=>f,$not:()=>m,$options:()=>k,$or:()=>d,$regex:()=>O,$size:()=>g,$where:()=>A});const u={type:`compound`,validate:M,parse(e,t,n){let r=p(e,t,n);return s(e.name,r)}},d=u,f={type:`compound`,validate:M,parse(t,n,r){let i=p(t,n,r);return new e(t.name,i)}};function p(e,t,n){let r=Array(t.length);for(let i=0;i<t.length;i++){let a=t[i];F(e,a,i),r[i]=n.parse(a)}return r}const m={type:`field`,validate(e,t){if(!(t&&(t instanceof RegExp||t.constructor===Object)))throw Error(`\"${e.name}\" expects to receive either regular expression or object of field operators`)},parse(n,r,i){let a=r instanceof RegExp?new t(`regex`,i.field,r):i.parse(r,i);return new e(n.name,[a])}},h={type:`field`,validate(e,t){if(!t||t.constructor!==Object)throw Error(`\"${e.name}\" expects to receive an object with nested query or field level operators`)},parse(e,r,{parse:i,field:a,hasOperators:o}){let s=o(r)?i(r,{field:n}):i(r);return new t(e.name,a,s)}},g={type:`field`,validate:P(`number`)},_={type:`field`,validate:j},v=_,y=_,b={type:`field`,validate(e,t){if(!Array.isArray(t)||t.length!==2)throw Error(`\"${e.name}\" expects an array with 2 numeric elements`)}},x={type:`field`,validate:P(`boolean`)},S={type:`field`,validate:N},C=S,w=C,T=C,E={type:`field`},D=E,O={type:`field`,validate(e,t){if(!(t instanceof RegExp)&&typeof t!=`string`)throw Error(`\"${e.name}\" expects value to be a regular expression or a string that represents regular expression`)},parse(e,n,r){let i=typeof n==`string`?new RegExp(n,r.query.$options||``):n;return new t(e.name,r.field,i)}},k={type:`field`,parse:()=>r},A={type:`document`,validate:P(`function`)};function j(e,t){if(!Array.isArray(t))throw Error(`\"${e.name}\" expects value to be an array`)}function M(e,t){if(j(e,t),!t.length)throw Error(`\"${e.name}\" expects to have at least one element in array`)}function N(e,t){if(!(typeof t==`string`||typeof t==`number`||t instanceof Date))throw Error(`\"${e.name}\" expects value to be comparable (i.e., string, number or date)`)}function P(e){return(t,n)=>{if(typeof n!==e)throw Error(`\"${t.name}\" expects value to be a \"${e}\"`)}}function F(e,t,n){let r=t;if(!r||r.constructor!==Object)throw Error(`\"${e.name}\" expects item at index ${n} to be an object`)}var I=class extends i{constructor(e){super(e,{defaultOperatorName:`$eq`,operatorToConditionName:e=>e.slice(1)})}parse(e,t){return t&&t.field?a(this.parseFieldOperators(t.field,e)):super.parse(e)}};const L=l;export{y as $all,u as $and,h as $elemMatch,E as $eq,x as $exists,C as $gt,S as $gte,_ as $in,w as $lt,T as $lte,b as $mod,D as $ne,v as $nin,f as $nor,m as $not,k as $options,d as $or,O as $regex,g as $size,A as $where,I as MongoQueryParser,L as allParsingInstructions,o as defaultParsers};\n//# sourceMappingURL=index.mjs.map","import type { MongoQuery } from '@ucast/mongo2js'\n\n// Minimal structural shape of the better-auth session consumed here.\n// Declared locally to avoid a workspace dependency cycle with `auth`\n// (auth depends on `ability` for its access-control config).\n// The full `auth` Session is structurally assignable to this type.\nexport type Session = {\n session: {\n activeOrganizationId?: string | null\n organizationRole?: string | null\n }\n user: {\n id?: string\n role?: string | null\n }\n}\n\nexport enum Audience {\n Backoffice = 'backoffice',\n Frontoffice = 'frontoffice',\n System = 'system',\n Public = 'public',\n}\n\nexport enum Subject {\n All = 'all',\n Todo = 'todo',\n User = 'user',\n Chat = 'chat',\n Agent = 'agent',\n SubAgent = 'subAgent',\n Document = 'document',\n AgentDocument = 'agent_document',\n AgentAnalytic = 'agent_analytic',\n McpServer = 'mcp_server',\n Media = 'media',\n RevisedAnswer = 'revised_answer',\n Organization = 'organization',\n Member = 'member',\n Lead = 'lead',\n MessageFeedback = 'message_feedback',\n Backoffice = 'backoffice',\n Frontoffice = 'frontoffice',\n System = 'system',\n Invitation = 'invitation',\n Crawler = 'crawler',\n ReasoningChat = 'reasoning_chat',\n OrganizationExternalAuth = 'organization_external_auth',\n AgentEndpoint = 'agent_endpoint',\n AgentEndpointLog = 'agent_endpoint_log',\n AgentApiTool = 'agent_api_tool',\n DocumentFolder = 'document_folder',\n Integration = 'integration',\n Notification = 'notification',\n PlatformConnection = 'platform_connection',\n}\n\n// action\nexport type Action =\n | 'create'\n | 'read'\n | 'update'\n | 'delete'\n | 'manage'\n | 'impersonate'\n | 'invite'\n | 'access'\n | 'clone'\n | 'ban'\n | 'unban'\n | 'change-role'\n | 'resend'\n | 'cancel'\n | 'execute'\n | 'refill'\n\nexport type Capability = {\n action: Action\n subject: Subject\n fields?: string[]\n condition?: MongoQuery\n inverted?: boolean\n}\n\nexport type CapabilitiesFactory = (\n currentSession?: Session | null,\n) => Capability[]\n","import type {\n MongoAbility,\n InferSubjects,\n ForcedSubject,\n FieldMatcher,\n} from '@casl/ability'\nimport type { Action, Capability, Subject } from './types'\nimport { type Session } from './types'\nimport { $or } from '@ucast/mongo2js'\nimport {\n AbilityBuilder,\n createMongoAbility,\n buildMongoQueryMatcher,\n createAliasResolver,\n subject as caslSubject,\n} from '@casl/ability'\nimport { organizationCapabilitiesByRole, userCapabilitiesByRole } from './roles'\nimport DefaultCapabilities from './roles/User'\nimport { createAccessControl } from 'better-auth/plugins'\nimport {\n adminAc,\n defaultStatements,\n memberAc,\n ownerAc,\n} from 'better-auth/plugins/organization/access'\n\nexport const OrganizationRoles = {\n admin: 'admin',\n owner: 'owner',\n member: 'member',\n user: 'user',\n} as const\n\nexport const UserRoles = {\n admin: 'admin',\n user: 'user',\n} as const\n\n// action alias\nconst resolveAction = createAliasResolver({\n modify: ['read', 'update', 'delete'],\n})\n\n// subject\nexport type AbilitySubject =\n | InferSubjects<'all' | Subject, true>\n | ForcedSubject<InferSubjects<'all' | Subject, true>>\nexport type AppAbility = MongoAbility<[Action, AbilitySubject]>\n\n// matcher\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst conditionsMatcher = buildMongoQueryMatcher({ $or } as Record<string, any>)\nconst fieldMatcher: FieldMatcher = (fields) => (field) => fields.includes(field)\n\nexport const isValidOrganizationRole = (\n role?: string | null,\n): role is keyof typeof OrganizationRoles => {\n if (!role) {\n return false\n }\n return role in OrganizationRoles\n}\n\nexport const isValidUserRole = (\n role?: string | null,\n): role is keyof typeof UserRoles => {\n if (!role) {\n return false\n }\n return role in UserRoles\n}\n\nexport const getOrganizationRoleCapabilities = (\n currentSession?: Session | null,\n): Capability[] => {\n const organizationRole = currentSession?.session?.organizationRole\n if (!isValidOrganizationRole(organizationRole)) {\n return DefaultCapabilities(currentSession)\n }\n const capabilities = organizationCapabilitiesByRole[organizationRole]\n if (typeof capabilities === 'function') {\n return capabilities(currentSession)\n }\n return capabilities\n}\n\nexport const getUserRoleCapabilities = (\n currentSession?: Session | null,\n): Capability[] => {\n const userRole = currentSession?.user?.role\n if (!isValidUserRole(userRole)) {\n return DefaultCapabilities(currentSession)\n }\n const capabilities = userCapabilitiesByRole[userRole]\n if (typeof capabilities === 'function') {\n return capabilities(currentSession)\n }\n return capabilities\n}\n\n/**\n * Builds the ability of one caller: the session's roles, or the guest rules\n * when there is no session. Every call returns a new instance and this package\n * keeps none: a server judges many callers at once, so an instance shared\n * between them is judged by whoever wrote it last. The backend builds one per\n * request (`request.ability`), the Platform MCP one per tool call, and the\n * frontend keeps its own for the single user of the tab.\n */\nexport const buildAbilityForSession = (\n currentSession?: Session | null,\n): AppAbility => {\n const { can, build, cannot } = new AbilityBuilder<AppAbility>(\n createMongoAbility,\n )\n const organizationRoleCapabilities =\n getOrganizationRoleCapabilities(currentSession)\n const userRoleCapabilities = getUserRoleCapabilities(currentSession)\n const capabilities = [\n ...organizationRoleCapabilities,\n ...userRoleCapabilities,\n ]\n capabilities.forEach((capability) => {\n const { action, subject, fields, condition, inverted } = capability\n if (inverted) {\n cannot(action, subject, fields, condition)\n return\n }\n can(action, subject, fields, condition)\n })\n return build({\n conditionsMatcher,\n resolveAction,\n fieldMatcher,\n })\n}\n\nexport type PermissionMap = Partial<Record<Action, Subject>>\n\nconst isEmptyObject = (value: unknown) =>\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0\n\n/**\n * Evaluates a route-style permission map ({ action: Subject }) against an\n * ability instance. When `payload` is provided it is bound as subject\n * conditions, same as the HTTP route preHandler does with `request.body`.\n * An empty object is checked like a missing payload: it says nothing about\n * the resource, and as a subject it has no field for a rule's conditions to\n * match, so a client that sent `{}` to a route taking no body (activate,\n * deactivate) was refused what the same request without a body got.\n * Returns the first denied pair, or null when every check passes.\n * Single source of truth for both the HTTP preHandler and the Platform MCP\n * tool handlers.\n */\nexport const findDeniedPermission = (\n abilityInstance: Pick<AppAbility, 'can'>,\n permissions: PermissionMap,\n payload?: unknown,\n): { action: Action; subject: Subject } | null => {\n let action: Action\n for (action in permissions) {\n const actionSubject = permissions[action]\n if (!actionSubject) {\n continue\n }\n const target =\n payload && !isEmptyObject(payload)\n ? caslSubject(\n actionSubject,\n payload as Record<PropertyKey, unknown>,\n )\n : actionSubject\n if (!abilityInstance.can(action, target)) {\n return { action, subject: actionSubject }\n }\n }\n return null\n}\n\nconst ac = createAccessControl(defaultStatements)\nconst adminRole = ac.newRole(adminAc.statements)\nconst ownerRole = ac.newRole(ownerAc.statements)\nconst memberRole = ac.newRole(memberAc.statements)\nconst userRole = ac.newRole(memberAc.statements)\n\nexport const betterAuthOrganizationSettings = {\n ac,\n roles: {\n owner: ownerRole,\n admin: adminRole,\n member: memberRole,\n user: userRole,\n },\n}\n\n/**\n * Whether a user is currently banned. A ban with no expiry is permanent, one\n * with an expiry in the future is still in force, one already elapsed is not.\n * Every admission path (API key, Platform MCP, voice callback) must apply the\n * same rule: a ban that holds in one path and not another is a hole.\n */\nexport const isUserBanned = (\n user:\n | { banned?: boolean | null; banExpires?: Date | null }\n | null\n | undefined,\n): boolean =>\n user?.banned === true &&\n (user.banExpires === null ||\n user.banExpires === undefined ||\n user.banExpires > new Date())\n\nexport * from './types'\nexport { subject } from '@casl/ability'\n","import { removeTrailingSlash } from 'utils'\n\nexport interface ResolveShortUrlsOptions {\n /** Extra headers to send (e.g. auth). */\n headers?: Record<string, string>\n /** Fetch credentials mode. Defaults to `'include'`. */\n credentials?: RequestCredentials\n}\n\n/**\n * Single implementation of the short-url batch resolve used across apps\n * (chatbot api client, frontend app root). Maps `/api/r/<hash>` short urls back\n * to their real target via `POST <backend>/api/r/resolve`.\n *\n * The redirect endpoint lives at `/api/r`, outside the JSON:API basePath, and\n * is unauthenticated. Returns an empty map (short urls left untouched) on any\n * failure so callers never have to handle errors.\n */\nexport async function resolveShortUrls(\n backendUrl: string,\n hashes: string[],\n options: ResolveShortUrlsOptions = {},\n): Promise<Record<string, string>> {\n try {\n const root = removeTrailingSlash(backendUrl)\n const response = await fetch(`${root}/api/r/resolve`, {\n method: 'POST',\n credentials: options.credentials ?? 'include',\n headers: {\n ...options.headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ hashes }),\n })\n if (!response.ok) {\n return {}\n }\n const data = (await response.json()) as {\n urls?: Record<string, string>\n }\n return data.urls ?? {}\n } catch {\n return {}\n }\n}\n","import { Audience } from 'ability'\nimport { ChatSchema, ChatsPublicSchema, VoiceSessionSchema } from 'models'\nimport type {\n AgentAccess,\n Chat,\n ChatWakeupState,\n DeviceContext,\n MessageFeedback,\n AgentPublic,\n MediaSource,\n VoiceSession,\n} from 'models'\nimport { addInitialSlash, removeTrailingSlash } from 'utils'\nimport { resolveShortUrls as resolveShortUrlsRequest } from './resolveShortUrls'\n\n// The chats endpoints respond with the full shape (frontoffice) or the\n// trimmed public one — same union the backend declares. Parsing coerces the\n// date fields (plain JSON strings otherwise); on mismatch keep the raw\n// payload instead of failing.\nconst ConversationSchema = ChatSchema.or(ChatsPublicSchema)\nfunction parseConversation(raw: unknown): Chat {\n const result = ConversationSchema.safeParse(raw)\n return (result.success ? result.data : raw) as Chat\n}\n\n/**\n * What went wrong, in words, from the problem+json the backend answers with\n * (`{ type, title, status, message }`). Falling straight back to the status\n * produced \"API error: 409\" on screen, which tells the reader nothing and hides\n * a message that was already there and already explains the fix.\n */\nasync function readErrorMessage(response: Response): Promise<string> {\n const fallback = `${response.status} ${response.statusText}`.trim()\n try {\n const body = (await response.json()) as {\n message?: string\n title?: string\n }\n return body.message?.trim() || body.title?.trim() || fallback\n } catch {\n return fallback\n }\n}\n\nexport interface ChatbotApiClientOptions {\n baseUrl: string\n basePath?: string\n headers?: () => Record<string, string> | undefined\n credentials?: RequestCredentials\n}\n\nexport interface SubmitFeedbackPayload {\n messageId: string\n chatId: string\n agentId: string\n vote?: 'upvote' | 'downvote'\n userQuestion: string\n assistantMessage: string\n comment?: string\n}\n\nexport interface SubmitLeadPayload {\n agentId: string\n chatId: string\n [key: string]: unknown\n}\n\n/** A file from the user's \"My files\" KB, or a spreadsheet of the chat with its\n * versions, as listed for a chat. */\nexport interface ChatbotFile {\n documentId: string\n kind: 'document' | 'spreadsheet'\n /** For a spreadsheet version, the attachment it is a version of. */\n sourceAttachmentId: string | null\n name: string | null\n mimeType: string | null\n indexStatus: string\n createdAt: string\n}\n\nexport interface ChatbotApiClient {\n getConversations(\n agentId: string,\n userId: string | undefined,\n ): Promise<Chat[]>\n getChat(agentId: string, chatId: string): Promise<Chat | null>\n /** The wakeup still waiting in a chat (spec agent-wakeup). */\n getChatWakeup(agentId: string, chatId: string): Promise<ChatWakeupState>\n /** The user's \"Stop\" of the chat's pending wakeup. */\n stopChatWakeup(agentId: string, chatId: string): Promise<ChatWakeupState>\n /** The chat is open in a visible tab: its wakeups mail nothing meanwhile. */\n markChatWakeupPresence(agentId: string, chatId: string): Promise<void>\n updateChatTitle(\n agentId: string,\n chatId: string,\n title: string,\n ): Promise<Chat>\n deleteChat(agentId: string, chatId: string): Promise<void>\n getMessageFeedbacks(chatId: string): Promise<MessageFeedback[]>\n submitMessageFeedback(\n payload: SubmitFeedbackPayload,\n ): Promise<MessageFeedback>\n submitLead(payload: SubmitLeadPayload): Promise<void>\n getAgent(orgSlug: string, agentId: string): Promise<AgentPublic>\n getAgentAccess(orgSlug: string, agentId: string): Promise<AgentAccess>\n getMediaUrl(agentId: string, chatId: string, storedFileName: string): string\n /** Like {@link getMediaUrl}, served as an attachment: the browser saves it. */\n getMediaDownloadUrl(\n agentId: string,\n chatId: string,\n storedFileName: string,\n ): string\n appendAuthToken(url: string): string\n uploadMedia(\n agentId: string,\n chatId: string,\n file: File,\n ): Promise<MediaSource>\n getChatEndpoint(agentId: string, type?: 'chat' | 'reasoning'): string\n expandSourceContext(\n agentId: string,\n documentId: string,\n chunkIndex: number,\n windowSize?: number,\n ): Promise<{ content: string }>\n downloadSourceDocument(\n agentId: string,\n documentId: string,\n ): Promise<{ downloadUrl: string; filename: string; mimeType: string }>\n reverseGeocode(\n lat: number,\n lon: number,\n lang?: string,\n ): Promise<string | undefined>\n forwardGeocode(\n query: string,\n lang?: string,\n ): Promise<\n { latitude: number; longitude: number; displayName: string } | undefined\n >\n getOAuthAuthorizeUrl(\n agentId: string,\n serverName: string,\n ): Promise<{ mcpServerId: string; authorizeUrl: string }>\n getOAuthConnectionStatus(\n agentId: string,\n serverName: string,\n ): Promise<{ mcpServerId: string; connected: boolean }>\n resolveShortUrls(hashes: string[]): Promise<Record<string, string>>\n getChatFiles(chatId: string): Promise<ChatbotFile[]>\n getChatFileDownloadUrl(documentId: string, inline?: boolean): string\n getChatFilePreviewUrl(documentId: string): string\n deleteChatFile(documentId: string): Promise<void>\n createVoiceSession(\n agentId: string,\n chatId?: string,\n /**\n * Everything the call inherits from the page it starts on. Sent once,\n * because the spoken turns arrive from the voice provider and carry\n * none of it.\n */\n context?: {\n deviceContext?: DeviceContext\n externalContext?: Record<string, unknown>\n },\n ): Promise<VoiceSession>\n closeVoiceSession(agentId: string, sessionId: string): Promise<void>\n}\n\nexport function createChatbotApiClient(\n options: ChatbotApiClientOptions,\n): ChatbotApiClient {\n const basePath = options.basePath\n ? addInitialSlash(options.basePath)\n : `/api/v1/${Audience.Public}`\n\n const baseUrl = `${removeTrailingSlash(options.baseUrl)}${basePath}`\n\n // \"My files\" lives under the frontoffice audience, not the agent's base\n // (which may be public, backoffice, …) — derive it by swapping the trailing\n // audience segment of basePath for `frontoffice`.\n const frontofficeBase = `${removeTrailingSlash(options.baseUrl)}${basePath.replace(\n /\\/[^/]+$/,\n `/${Audience.Frontoffice}`,\n )}`\n\n async function request<T>(\n url: string,\n init?: RequestInit,\n responseType: 'json' | 'void' = 'json',\n ): Promise<T> {\n const response = await fetch(`${baseUrl}${url}`, {\n credentials: options.credentials ?? 'include',\n ...init,\n headers: {\n ...options.headers?.(),\n ...init?.headers,\n },\n })\n\n if (!response.ok) {\n throw new Error(await readErrorMessage(response))\n }\n\n if (responseType === 'void' || response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n }\n\n return {\n async getConversations(agentId, userId) {\n const userFilter = userId\n ? `&filter[userId]=${encodeURIComponent(userId)}`\n : ''\n const conversations = await request<unknown[]>(\n `/agents/${encodeURIComponent(agentId)}/chats?sort=-lastMessageAt&page[size]=100${userFilter}`,\n )\n return conversations.map(parseConversation)\n },\n\n async getChatFiles(chatId) {\n const response = await fetch(\n `${frontofficeBase}/me/documents?filter[chatId]=${encodeURIComponent(chatId)}&page[size]=100`,\n {\n credentials: options.credentials ?? 'include',\n headers: { ...options.headers?.() },\n },\n )\n if (!response.ok) {\n throw new Error(\n `API error: ${response.status} ${response.statusText}`,\n )\n }\n return (await response.json()) as ChatbotFile[]\n },\n\n getChatFileDownloadUrl(documentId, inline) {\n const suffix = inline ? '?inline=true' : ''\n // appendAuthToken carries a bearer in the query so <img>/<a>\n // subresources (which can't set an Authorization header) authorize\n // cross-origin in the embedded widget; no-op for cookie auth.\n return this.appendAuthToken(\n `${frontofficeBase}/me/documents/${encodeURIComponent(documentId)}/download${suffix}`,\n )\n },\n\n getChatFilePreviewUrl(documentId) {\n // Small resized preview blob for row thumbnails (see download\n // endpoint ?preview=true); auth token carried for cross-origin <img>.\n return this.appendAuthToken(\n `${frontofficeBase}/me/documents/${encodeURIComponent(documentId)}/download?preview=true`,\n )\n },\n\n async deleteChatFile(documentId) {\n const response = await fetch(\n `${frontofficeBase}/me/documents/${encodeURIComponent(documentId)}`,\n {\n method: 'DELETE',\n credentials: options.credentials ?? 'include',\n headers: { ...options.headers?.() },\n },\n )\n if (!response.ok) {\n throw new Error(\n `API error: ${response.status} ${response.statusText}`,\n )\n }\n },\n\n async getChat(agentId, chatId) {\n const result = await request<Chat | undefined>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}`,\n )\n return result ? parseConversation(result) : null\n },\n\n async getChatWakeup(agentId, chatId) {\n return request<ChatWakeupState>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/wakeup`,\n )\n },\n\n async stopChatWakeup(agentId, chatId) {\n return request<ChatWakeupState>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/wakeup`,\n { method: 'DELETE' },\n )\n },\n\n async markChatWakeupPresence(agentId, chatId) {\n await request<void>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/wakeup/presence`,\n { method: 'PUT' },\n 'void',\n )\n },\n\n async updateChatTitle(agentId, chatId, title) {\n return parseConversation(\n await request<Chat>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}`,\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title }),\n },\n ),\n )\n },\n\n async deleteChat(agentId, chatId) {\n await request<void>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}`,\n { method: 'DELETE' },\n 'void',\n )\n },\n\n async getMessageFeedbacks(chatId) {\n return request<MessageFeedback[]>(\n `/message-feedbacks?filter[chatId]=${encodeURIComponent(chatId)}&page[size]=200`,\n )\n },\n\n async submitMessageFeedback(payload) {\n return request<MessageFeedback>('/message-feedbacks', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n })\n },\n\n async submitLead(payload) {\n await request<void>(\n '/leads',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n 'void',\n )\n },\n\n async getAgent(orgSlug, agentId) {\n return request<AgentPublic>(\n `/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}`,\n )\n },\n\n async getAgentAccess(orgSlug, agentId) {\n return request<AgentAccess>(\n `/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}/access`,\n )\n },\n\n async uploadMedia(agentId, chatId, file) {\n const formData = new FormData()\n formData.append('file', file)\n const response = await fetch(\n `${baseUrl}/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/media/upload`,\n {\n method: 'POST',\n credentials: options.credentials ?? 'include',\n // Do NOT set Content-Type — browser sets multipart/form-data with boundary automatically\n headers: options.headers?.(),\n body: formData,\n },\n )\n if (!response.ok) {\n const text = await response.text().catch(() => '')\n let title = `Upload failed: ${response.status}`\n try {\n title =\n (JSON.parse(text) as { title?: string }).title ?? title\n } catch {\n // ignore parse errors\n }\n throw new Error(title)\n }\n return response.json() as Promise<MediaSource>\n },\n\n getChatEndpoint(agentId, type = 'chat') {\n const path = type === 'reasoning' ? 'reasoning-chat' : 'chat'\n return `${baseUrl}/agents/${encodeURIComponent(agentId)}/${path}`\n },\n\n appendAuthToken(url) {\n const bearer = options\n .headers?.()\n ?.[`Authorization`]?.slice('Bearer '.length)\n if (!bearer) {\n return url\n }\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}token=${encodeURIComponent(bearer)}`\n },\n\n getMediaUrl(agentId, chatId, storedFileName) {\n const base = `${baseUrl}/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/media/${encodeURIComponent(storedFileName)}/view`\n return this.appendAuthToken(base)\n },\n\n getMediaDownloadUrl(agentId, chatId, storedFileName) {\n const base = `${baseUrl}/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/media/${encodeURIComponent(storedFileName)}/download`\n return this.appendAuthToken(base)\n },\n\n async expandSourceContext(\n agentId,\n documentId,\n chunkIndex,\n windowSize = 2,\n ) {\n return request<{ content: string }>(\n `/agents/${encodeURIComponent(agentId)}/sources/expand-context`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n documentId,\n chunkIndex,\n windowSize,\n }),\n },\n )\n },\n\n async downloadSourceDocument(agentId, documentId) {\n return request<{\n downloadUrl: string\n filename: string\n mimeType: string\n }>(\n `/agents/${encodeURIComponent(agentId)}/sources/documents/${encodeURIComponent(documentId)}/download`,\n )\n },\n\n async reverseGeocode(lat, lon, lang) {\n const params = new URLSearchParams({\n lat: String(lat),\n lon: String(lon),\n })\n if (lang) {\n params.set('lang', lang)\n }\n try {\n const data = await request<{ displayName?: string }>(\n `/geocoder/reverse?${params}`,\n )\n return data.displayName\n } catch {\n return undefined\n }\n },\n\n async forwardGeocode(query, lang) {\n const params = new URLSearchParams({ q: query })\n if (lang) {\n params.set('lang', lang)\n }\n try {\n return await request<{\n latitude: number\n longitude: number\n displayName: string\n }>(`/geocoder/forward?${params}`)\n } catch {\n return undefined\n }\n },\n\n async getOAuthAuthorizeUrl(agentId, serverName) {\n const params = new URLSearchParams({ serverName })\n return request<{ mcpServerId: string; authorizeUrl: string }>(\n `/agents/${encodeURIComponent(agentId)}/mcp-oauth/authorize?${params}`,\n )\n },\n\n async getOAuthConnectionStatus(agentId, serverName) {\n const params = new URLSearchParams({ serverName })\n return request<{ mcpServerId: string; connected: boolean }>(\n `/agents/${encodeURIComponent(agentId)}/mcp-oauth/status?${params}`,\n )\n },\n\n /**\n * Opens a voice session on the conversation currently on screen, so the\n * spoken turns land in the same thread the user can keep typing into.\n * The signed URL it returns is short-lived and per session: the provider\n * credential stays on the server.\n */\n async createVoiceSession(agentId, chatId, context) {\n return VoiceSessionSchema.parse(\n await request<unknown>(\n `/agents/${encodeURIComponent(agentId)}/voice/session`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n ...(chatId ? { chatId } : {}),\n // Sent once for the whole call: the spoken turns\n // come from the provider and carry nothing about\n // this browser nor about the page it runs on.\n ...(context?.deviceContext\n ? { deviceContext: context.deviceContext }\n : {}),\n ...(context?.externalContext\n ? { externalContext: context.externalContext }\n : {}),\n }),\n },\n ),\n )\n },\n\n /**\n * `keepalive` on purpose: this is the call that settles the minutes of a\n * session, and it is often made while the page is going away (hang up on\n * unload, tab closed). Without it the browser is free to cancel it.\n */\n async closeVoiceSession(agentId, sessionId) {\n await request<void>(\n `/agents/${encodeURIComponent(agentId)}/voice/session/${encodeURIComponent(sessionId)}`,\n { method: 'DELETE', keepalive: true },\n 'void',\n )\n },\n\n resolveShortUrls(hashes) {\n return resolveShortUrlsRequest(options.baseUrl, hashes, {\n headers: options.headers?.(),\n credentials: options.credentials,\n })\n },\n }\n}\n"],"ignoreList":[2,3],"mappings":"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"}
1
+ {"version":3,"file":"createChatbotApiClient-G3Tt1I67.js","names":["z.object","z.coerce.date","z.enum","z.string","z.array","z.boolean","z.number","z.object","z.literal","z.string","z.url","z.record","z.unknown","z.discriminatedUnion","z.array","z.enum","z.number","z.boolean","z.coerce.date","c","l","d","f","s","n","e","t","i","r","resolveShortUrlsRequest","string","url","number","literal","array","_enum","boolean","discriminatedUnion","object","unknown","record","date","MIME_TYPE_REGEX","VoiceSessionSchema","DeviceContextSchema","resolveToolName","AgentRankingSchema","AgentReasoningSchema","AgentGatewayOptionsSchema","AgentWebSearchSchema","zodQs","AgentBuiltInTool","AgentSearchMode","UNAVAILABLE_TOOL_ERROR_PATTERN","removeTrailingSlash","addInitialSlash","AbuseCategory","\"Harassment\"","\"HateSpeech\"","\"SexualContent\"","\"SelfHarm\"","\"Violence\"","\"PromptInjection\"","\"DataExtraction\"","\"Spam\"","\"OffTopicPersistent\"","\"Impersonation\"","AbuseConfidence","\"Low\"","\"Medium\"","\"High\"","LlmIssueCategory","\"FalseSuccess\"","\"Hallucination\"","\"OffBrand\"","\"DataLeak\"","\"InappropriateTone\"","\"RefusalLoop\"","\"Repetition\"","\"FailedAction\"","\"EmptyReply\"","\"StuckFlow\"","ConversationAnalysisTrigger","\"SummaryCycle\"","\"AgentRequest\"","\"Manual\"","UserEngagement","\"Disengaged\"","UserTone","\"Polite\"","\"Neutral\"","\"Impatient\"","\"Aggressive\"","\"Abusive\"","Sentiment","\"Positive\"","\"Negative\"","\"Frustrated\"","\"Excited\"","SentimentTrend","\"Improving\"","\"Stable\"","\"Degrading\"","CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS","ConversationAnalysisSchema","TextPartSchema","FilePartSchema","MessagePartSchema","BlockedReasonCode","\"SevereAbuse\"","\"HighRiskScore\"","\"RepeatedWarnings\"","\"Web\"","\"WhatsApp\"","\"Teams\"","\"Voice\"","\"Api\"","\"Reasoning\"","\"Endpoint\"","ChatChannel","summarizeToolSelection","message","decision","groupOfKey","group","key","groupByName","used","enabled","part","toolName","names","name","groupId","selected","seeded","groups","b","a","TURN_EVALUATION_QUESTION_IDS","TOOL_TERMINAL_STATES","ChatSchema","ChatsPublicSchema","e","t","n","r","i","c$1","l$1","c","y","u","h","E","x","C","S","_","w","T","D","v","f","m","k","d","O","g","A","M","p","n$1","i$1","n$2","i$3","o","s","r$1","P","j","N","i$5","F","Audience","\"Backoffice\"","\"Frontoffice\"","\"System\"","\"Public\"","createAliasResolver","buildMongoQueryMatcher","ac","createAccessControl","defaultStatements","adminAc","ownerAc","memberAc","resolveShortUrls","root","backendUrl","response","options","ConversationSchema","parseConversation","result","raw","readErrorMessage","fallback","body","createChatbotApiClient","basePath","baseUrl","frontofficeBase","request","init","responseType","userFilter","userId","agentId","chatId","suffix","inline","documentId","payload","orgSlug","formData","file","text","title","type","bearer","`Authorization`","base","storedFileName","params","lat","lon","lang","query","context","sessionId","hashes"],"sources":["../../../../packages/models/src/schema/ConversationAnalysis.ts","../../../../packages/models/src/schema/Chat.ts","../../../../node_modules/.pnpm/@ucast+core@2.0.0/node_modules/@ucast/core/dist/esm/index.mjs","../../../../node_modules/.pnpm/@ucast+mongo@3.0.0/node_modules/@ucast/mongo/dist/esm/index.mjs","../../../../packages/ability/src/types.ts","../../../../packages/ability/src/index.ts","../../../../packages/composable/src/chatbot/api/resolveShortUrls.ts","../../../../packages/composable/src/chatbot/api/createChatbotApiClient.ts"],"sourcesContent":["import * as z from 'zod'\n\nexport enum AbuseCategory {\n Harassment = 'harassment',\n HateSpeech = 'hate_speech',\n SexualContent = 'sexual_content',\n SelfHarm = 'self_harm',\n Violence = 'violence',\n PromptInjection = 'prompt_injection',\n DataExtraction = 'data_extraction',\n Spam = 'spam',\n OffTopicPersistent = 'off_topic_persistent',\n Impersonation = 'impersonation',\n}\n\nexport enum AbuseConfidence {\n Low = 'low',\n Medium = 'medium',\n High = 'high',\n}\n\nexport enum LlmIssueCategory {\n FalseSuccess = 'false_success',\n Hallucination = 'hallucination',\n OffBrand = 'off_brand',\n DataLeak = 'data_leak',\n InappropriateTone = 'inappropriate_tone',\n RefusalLoop = 'refusal_loop',\n Repetition = 'repetition',\n FailedAction = 'failed_action',\n EmptyReply = 'empty_reply',\n StuckFlow = 'stuck_flow',\n}\n\nexport enum ConversationAnalysisTrigger {\n SummaryCycle = 'summary_cycle',\n AgentRequest = 'agent_request',\n Manual = 'manual',\n}\n\nexport enum UserEngagement {\n High = 'high',\n Medium = 'medium',\n Low = 'low',\n Disengaged = 'disengaged',\n}\n\nexport enum UserTone {\n Polite = 'polite',\n Neutral = 'neutral',\n Impatient = 'impatient',\n Aggressive = 'aggressive',\n Abusive = 'abusive',\n}\n\nexport enum Sentiment {\n Positive = 'positive',\n Neutral = 'neutral',\n Negative = 'negative',\n Frustrated = 'frustrated',\n Excited = 'excited',\n}\n\nexport enum SentimentTrend {\n Improving = 'improving',\n Stable = 'stable',\n Degrading = 'degrading',\n}\n\n/** Longest abuse or LLM issue summary an analysis stores. */\nexport const CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS = 1000\n\nexport const ConversationAnalysisSchema = z.object({\n // --- Metadata (set programmatically, not by the LLM) ---\n analyzedAt: z.coerce.date().describe('When the analysis was generated.'),\n analysisTrigger: z\n .enum(ConversationAnalysisTrigger)\n .describe('What triggered this analysis run.'),\n\n // --- Sentiment & Tone ---\n sentiment: z\n .enum(Sentiment)\n .describe('Overall user sentiment in the conversation.'),\n sentimentTrend: z\n .enum(SentimentTrend)\n .describe('How the user sentiment evolved during the conversation.'),\n userTone: z\n .enum(UserTone)\n .describe('Predominant tone of the user messages.'),\n\n // --- Language ---\n language: z\n .string()\n .max(10)\n .describe(\n 'ISO 639-1 language code of the conversation (e.g. \"en\", \"it\").',\n ),\n\n // --- Topics ---\n topics: z\n .array(z.string().max(100))\n .max(10)\n .describe('Main topics discussed, as short lowercase labels.'),\n\n // --- User Abuse Detection ---\n userAbuseDetected: z\n .boolean()\n .describe(\n 'Whether user abuse was detected. If false, userAbuseCategories MUST be empty.',\n ),\n userAbuseCategories: z\n .array(z.enum(AbuseCategory))\n .default([])\n .describe(\n 'Abuse categories detected. Non-empty only if userAbuseDetected is true.',\n ),\n userAbuseConfidence: z\n .enum(AbuseConfidence)\n .optional()\n .describe(\n 'Confidence level of the abuse detection. Set only if userAbuseDetected is true.',\n ),\n userAbuseSummary: z\n .string()\n .max(CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS)\n .optional()\n .describe(\n 'Brief description of the abusive behavior detected. Always write in English. Set only if userAbuseDetected is true.',\n ),\n\n // --- LLM Quality Issues ---\n llmIssueDetected: z\n .boolean()\n .describe(\n 'Whether an LLM quality issue was detected. If false, llmIssueCategories MUST be empty.',\n ),\n llmIssueCategories: z\n .array(z.enum(LlmIssueCategory))\n .default([])\n .describe(\n 'LLM issue categories detected. Non-empty only if llmIssueDetected is true.',\n ),\n llmIssueSummary: z\n .string()\n .max(CONVERSATION_ANALYSIS_SUMMARY_MAX_CHARS)\n .optional()\n .describe(\n 'Brief description of the LLM quality issue detected. Always write in English. Set only if llmIssueDetected is true.',\n ),\n\n // --- Engagement ---\n userEngagement: z\n .enum(UserEngagement)\n .describe('Level of user engagement in the conversation.'),\n conversationGoalMet: z\n .boolean()\n .optional()\n .describe(\n 'Whether the user seems to have achieved what they came for. Leave undefined if unclear.',\n ),\n\n // --- Risk Score ---\n riskScore: z\n .number()\n .int()\n .min(0)\n .max(100)\n .describe(\n 'Overall risk score (0 = safe, 100 = critical). Combination of abuse severity, persistence and escalation.',\n ),\n})\n\nexport type ConversationAnalysis = z.infer<typeof ConversationAnalysisSchema>\n","import * as z from 'zod'\nimport { resolveToolName, zodQs } from '../utils'\nimport type { UIMessage, LanguageModelUsage } from 'ai'\nimport { ConversationAnalysisSchema } from './ConversationAnalysis'\nimport {\n AgentBuiltInTool,\n ENABLE_TOOLS_TOOL,\n AgentGatewayOptionsSchema,\n AgentReasoningSchema,\n AgentWebSearchSchema,\n AgentSearchMode,\n AgentRankingSchema,\n} from './Agent'\nimport { MIME_TYPE_REGEX } from './Media'\nimport type { PlatformContext } from './Platform'\nimport { UNAVAILABLE_TOOL_ERROR_PATTERN } from './StreamError'\n\nimport { DeviceContextSchema, type DeviceContext } from './DeviceContext'\n\nexport { DeviceContextSchema, type DeviceContext }\n\nconst TextPartSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n})\n\nconst FilePartSchema = z.object({\n type: z.literal('file'),\n mediaType: z.string().regex(MIME_TYPE_REGEX),\n url: z.url(),\n filename: z.string().optional(),\n providerMetadata: z\n .record(z.string(), z.record(z.string(), z.unknown()))\n .optional(),\n})\n\nconst MessagePartSchema = z.discriminatedUnion('type', [\n TextPartSchema,\n FilePartSchema,\n])\n\nexport const ChatRequestSchema = z.object({\n id: z.string(),\n messages: z.array(\n z.object({\n id: z.string().optional(),\n role: z.enum(['assistant', 'user']),\n content: z.string(),\n parts: z.array(MessagePartSchema),\n createdAt: z.string().optional(),\n }),\n ),\n model: z.string().optional(),\n temperature: z.number().optional(),\n prompt: z.string().optional(),\n maxOutputTokens: z.number().positive().optional(),\n presencePenalty: z.number().min(-2).max(2).optional(),\n frequencyPenalty: z.number().min(-2).max(2).optional(),\n searchMode: z.enum(AgentSearchMode).optional(),\n limit: z.number().optional(),\n ranking: AgentRankingSchema.optional(),\n reasoning: AgentReasoningSchema,\n webSearch: AgentWebSearchSchema.optional(),\n maxStepCount: z.number().int().min(1).max(40).optional(),\n disabledTools: z.array(z.enum(AgentBuiltInTool)).optional(),\n fallbackModels: z.array(z.string()).optional(),\n gatewayOptions: AgentGatewayOptionsSchema.partial().optional(),\n deviceContext: DeviceContextSchema.optional(),\n externalContext: z.record(z.string(), z.unknown()).optional(),\n smoothStream: z.boolean().optional(),\n})\n\nexport type ChatRequest = z.infer<typeof ChatRequestSchema>\n\n/**\n * What the chat route validates on the way in.\n *\n * Deliberately not `ChatRequestSchema`: a turn resumed after a client tool or\n * a tool approval posts the assistant message back, whose parts are tool\n * calls, and the part union above accepts text and files only. Pinning the\n * body to it would answer 400 to a legitimate resume. So this validates the\n * envelope the turn cannot run without and lets the rest through untouched\n * (`loose`), which is also why the overrides the client sends still reach the\n * service.\n *\n * The id is minted by the client and read back as a row key: without it the\n * lookup ran with `undefined` and the route answered 500 instead of 400\n * (found 2026-09-21).\n */\nexport const ChatRequestEnvelopeSchema = z\n .object({\n id: z.string().min(1),\n messages: z.array(z.object({ role: z.string() }).loose()).min(1),\n })\n .loose()\n\nexport enum BlockedReasonCode {\n SevereAbuse = 'severe_abuse',\n HighRiskScore = 'high_risk_score',\n RepeatedWarnings = 'repeated_warnings',\n}\n\nexport type ChatMetadata = {\n ipAddress: string\n /** HTTP `Origin` of the request, empty for a server-to-server caller. */\n origin: string\n userAgent: string\n /**\n * Non-default transport the conversation arrived through (for example\n * `openai-api`), so cost and usage reports can isolate it. Absent for the\n * web and widget chat.\n */\n transport?: string\n}\n\n/**\n * Channel a conversation arrived through, as the analytics slice it.\n *\n * Derived at read time and never stored: a platform conversation is identified\n * by `chats.metadata.platform` ({@link PlatformType}), every other non-web\n * surface by `chats.metadata.transport` ({@link ChatTransport}), and a chat\n * carrying neither marker is the web chat or the widget (the historical\n * default, which is why those rows have nothing to read). `reasoning_chats`\n * and `agent_endpoint_logs` have no metadata at all, so each of those tables\n * is a channel by itself.\n *\n * Not to be confused with {@link AgentChannel}, which says where an agent is\n * published (frontoffice, app, widget): this says where a conversation came\n * from.\n *\n * Only the platforms we actually run are listed. `PlatformType` declares five\n * more, and one of those appearing in the data is reported under its own raw\n * value rather than folded into a bucket, so a channel nobody expected shows\n * up in the dashboard instead of hiding inside `other`.\n */\nexport enum ChatChannel {\n /** Web chat and embeddable widget: no marker on the row. */\n Web = 'web',\n WhatsApp = 'whatsapp',\n Teams = 'teams',\n /** Spoken session opened by us, `transport = voice`. */\n Voice = 'voice',\n /** OpenAI-compatible REST surface, `transport = openai-api`. */\n Api = 'api',\n /** Every row of `reasoning_chats`: the reasoning endpoint. */\n Reasoning = 'reasoning',\n /** Every row of `agent_endpoint_logs`: the custom agent endpoints. */\n Endpoint = 'endpoint',\n}\n\nexport const ChatChannelSchema = z.enum(ChatChannel)\n\nexport type ChatMessageActions =\n 'show-info' | 'revise' | 'regenerate' | 'upvote' | 'downvote' | 'feedback'\n\nexport type Chat = z.infer<typeof ChatSchema>\nexport type ChatsQuerystring = z.infer<typeof ChatsQuerystringSchema>\n\nexport type UIChatMessageDeviceContext = DeviceContext\n\n/** Kinds of tool group the working set decides on, one group per MCP server. */\nexport type ToolGroupKind = 'mcp' | 'api' | 'subagent'\n\n/**\n * What the working set decided for a turn (spec tool-catalogue-working-set,\n * F4). Group ids are those of {@link ToolCatalogueRecord}; the groups the model\n * enabled later in the turn are read from its `enableTools` calls.\n */\nexport type ToolWorkingSetRecord = {\n /** `shadow` recorded the decision and exposed everything, `active` applied it. */\n mode: 'shadow' | 'active'\n /** Groups exposed from the first step: the judged ones and the seed. */\n selected: string[]\n /** Groups the conversation seeded, exposed whatever the judgment. */\n seeded: string[]\n /** Probability the evaluation model gave each judged group, two decimals. */\n probabilities: Record<string, number>\n latencyMs: number\n /**\n * Time the evaluation was given: short in active mode, where the turn\n * waits for it, longer in shadow mode, where it runs alongside.\n */\n budgetMs: number\n /** Probability from which a judged group is exposed. */\n threshold: number\n /**\n * What the evaluation cost in USD, the amount charged to the organization.\n * Absent when it failed: nothing is charged then.\n */\n cost?: number\n inputTokens?: number\n /**\n * The evaluation answered with an error or not within the budget, and\n * every group stayed exposed.\n */\n failed?: boolean\n}\n\n/**\n * The part of a turn's tool catalogue the working set acts on (spec\n * tool-catalogue-working-set, F2): which MCP servers, API tools and sub-agents\n * were eligible, identified by id and not by the public keys, which collide\n * across servers. Enough to make a measurement repeatable without storing the\n * schemas.\n */\nexport type ToolCatalogueRecord = {\n /** Short hash of the eligible keys and their groups: two turns with the same set agree on it. */\n fingerprint: string\n groups: Array<{\n id: string\n kind: ToolGroupKind\n name: string\n /**\n * Keys of the group offered this turn: what attributes a call in the\n * message to its group, since a key names a different server's tool\n * in another turn.\n */\n keys: string[]\n }>\n workingSet?: ToolWorkingSetRecord\n}\n\n/** One group of a turn's catalogue, read against what the turn did with it. */\nexport type ToolSelectionGroup = {\n id: string\n kind: ToolGroupKind\n name: string\n tools: number\n /** Absent when the evaluation failed. */\n probability?: number\n /** Exposed from the first step in active mode, or would have been in shadow mode. */\n selected: boolean\n seeded: boolean\n /**\n * Brought back during the turn, by `enableTools` or by a direct call to\n * one of its tools that the model was refused as unavailable.\n */\n enabled: boolean\n /**\n * The model called one of its tools, whatever came of the call (an error,\n * a denied approval): the turn needed the group.\n */\n used: boolean\n}\n\nexport type ToolSelectionSummary = {\n decision: ToolWorkingSetRecord\n /** Most probable first, then by name. */\n groups: ToolSelectionGroup[]\n /**\n * Groups the turn used that the decision left out. In active mode the\n * model had to bring each one back, in shadow mode it would have had to:\n * the working set's miss, the figure F3 of the spec counts.\n */\n missed: number\n}\n\ntype SummarizedPart = {\n type: string\n toolName?: string\n state?: string\n input?: unknown\n errorText?: string\n}\n\n/**\n * The working set's decision on a turn next to what the turn did: which\n * groups it exposed, which the model brought back and which it used. Read\n * from the stored answer, whose metadata carries the record and whose parts\n * carry the calls, the way the backend read them during the turn: a call\n * counts under the name the repair would give it, and an `enableTools` call\n * only once it ran. Undefined when the working set did not decide.\n */\nexport function summarizeToolSelection(message: {\n parts?: ReadonlyArray<unknown>\n metadata?: { toolCatalogue?: ToolCatalogueRecord }\n}): ToolSelectionSummary | undefined {\n const record = message.metadata?.toolCatalogue\n const decision = record?.workingSet\n if (!record || !decision) {\n return undefined\n }\n const groupOfKey = new Map(\n record.groups.flatMap((group) =>\n group.keys.map((key) => [key, group.id] as const),\n ),\n )\n const groupByName = new Map(\n record.groups.map((group) => [group.name, group.id] as const),\n )\n const used = new Set<string>()\n const enabled = new Set<string>()\n for (const part of (message.parts ?? []) as SummarizedPart[]) {\n const toolName =\n part.type === 'dynamic-tool'\n ? part.toolName\n : part.type.startsWith('tool-')\n ? part.type.slice(5)\n : undefined\n if (!toolName) {\n continue\n }\n if (toolName === ENABLE_TOOLS_TOOL) {\n // A call whose input failed validation enabled nothing.\n const names =\n part.state === 'output-available'\n ? (part.input as { groups?: unknown })?.groups\n : undefined\n for (const name of Array.isArray(names) ? names : []) {\n const groupId = groupByName.get(String(name))\n if (groupId) {\n enabled.add(groupId)\n }\n }\n continue\n }\n const key = resolveToolName(toolName, groupOfKey.keys())\n const groupId = key && groupOfKey.get(key)\n if (!groupId) {\n continue\n }\n // A call to a hidden tool is refused as unavailable, and that refusal\n // is how the model asked for its group back.\n if (\n part.state === 'output-error' &&\n UNAVAILABLE_TOOL_ERROR_PATTERN.test(part.errorText ?? '')\n ) {\n enabled.add(groupId)\n } else {\n used.add(groupId)\n }\n }\n const selected = new Set(decision.selected)\n const seeded = new Set(decision.seeded)\n const groups = record.groups\n .map((group) => ({\n id: group.id,\n kind: group.kind,\n name: group.name,\n tools: group.keys.length,\n probability: decision.probabilities[group.id],\n selected: selected.has(group.id),\n seeded: seeded.has(group.id),\n enabled: enabled.has(group.id),\n used: used.has(group.id),\n }))\n .sort(\n (a, b) =>\n (b.probability ?? -1) - (a.probability ?? -1) ||\n a.name.localeCompare(b.name),\n )\n return {\n decision,\n groups,\n missed: groups.filter((group) => group.used && !group.selected).length,\n }\n}\n\nexport type UIChatMessageMetadata = {\n /** Unix timestamp (ms) when the stream started */\n createdAt?: number\n /** Unix timestamp (ms) when the stream finished */\n completedAt?: number\n /** Canonical model ID used for the request (e.g. `google/gemini-3-flash`) */\n model?: string\n /** Total tokens consumed across all steps */\n totalTokens?: number\n /** Per-tool-call durations in ms, keyed by tool call ID */\n partTimings?: Record<string, number>\n /** Client device context sent with the request */\n deviceContext?: UIChatMessageDeviceContext\n /** Platform channel context (WhatsApp/Teams), the device-context equivalent for platform turns */\n platformContext?: PlatformContext\n /** External context provided by the host application and validated server-side */\n externalContext?: Record<string, unknown>\n /** Provider that ultimately served the request (e.g. `vertex`, `openai`) */\n resolvedProvider?: string\n /** Actual model ID as exposed by the resolved provider (e.g. `gemini-3-flash-preview`) */\n resolvedModelId?: string\n /** Market cost of the request in USD, as a numeric string */\n cost?: string\n /** Number of model-level routing attempts made by the gateway */\n modelAttemptCount?: number\n /** Total number of provider-level attempts (includes retries across providers) */\n totalProviderAttemptCount?: number\n /** Whether Zero Data Retention was active for this request */\n zeroDataRetention?: boolean\n /** Whether the provider was instructed not to use the prompt for model training */\n disallowPromptTraining?: boolean\n /** Vercel AI Gateway generation ID, useful for tracing in the Vercel dashboard */\n generationId?: string\n /** Tokens served from the provider's prompt cache (e.g. Gemini context caching) */\n cachedTokens?: number\n /** Provider traffic tier (e.g. `PROVISIONED_THROUGHPUT`, `ON_DEMAND`) */\n trafficType?: string\n /**\n * Transport the message travelled through ({@link ChatTransport}), when it\n * was not the web chat itself: `voice` marks a spoken exchange (the user\n * text is the call transcription, the assistant text was read aloud),\n * `openai-api` an API turn. Absent on plain web messages.\n */\n transport?: string\n /**\n * The MCP servers, API tools and sub-agents this turn could use, and the\n * working set's decision on them. Absent when the agent has none. Kept\n * from a public reader: streamed only to the organization's own audiences\n * (on the closing finish), and removed from whatever else leaves the\n * organization ({@link withoutToolCatalogue}).\n */\n toolCatalogue?: ToolCatalogueRecord\n /**\n * The evaluation of the turn after the reply (spec post-turn-evaluation):\n * a probability per question. Written after the answer, and removed from\n * a public read ({@link withoutTurnEvaluation}).\n */\n turnEvaluation?: TurnEvaluationRecord\n /**\n * Set on the user message a wakeup injected (spec agent-wakeup): its text\n * is the prompt the agent left for itself, not words the user typed.\n */\n wakeup?: UIChatMessageWakeup\n}\n\n/** The wakeup a seed message belongs to (spec agent-wakeup). */\nexport type UIChatMessageWakeup = {\n id: string\n loopId: string\n iteration: number\n reason: string\n}\n\n/**\n * The questions of the post-turn evaluation, in the order they are asked and\n * listed. The backend's questions are typed against it, so the two cannot\n * drift. A reader orders by this list and not by the record: jsonb keeps the\n * keys of an object sorted by length, not in the order they were written.\n */\nexport const TURN_EVALUATION_QUESTION_IDS = [\n 'durableFact',\n 'abusive',\n 'manipulation',\n 'asksHuman',\n 'missingInfo',\n 'informationGap',\n] as const\n\nexport type TurnEvaluationQuestionId =\n (typeof TURN_EVALUATION_QUESTION_IDS)[number]\n\n/**\n * The evaluation model's answers on a finished turn (spec\n * post-turn-evaluation, F1). Recorded in shadow only: nothing reads it yet.\n */\nexport type TurnEvaluationRecord = {\n /**\n * The wording of the questions: a threshold holds only for the wording\n * it was measured on, so a record says which one it answered.\n */\n version: number\n mode: 'shadow'\n /** Probability per question, two decimals. Empty when the request failed. */\n probabilities: Record<string, number>\n latencyMs: number\n budgetMs: number\n /** Market cost of the request in USD. */\n cost?: number\n inputTokens?: number\n /** The request failed or ran past its budget: no answer was recorded. */\n failed?: true\n}\n\nexport type UIChatMessage = UIMessage & {\n metadata?: UIChatMessageMetadata\n}\n\n/**\n * The history without the turn evaluations, for a public read: a probability\n * of abuse on a user must not reach the widget. Kept apart from\n * {@link withoutToolCatalogue}, which the data export uses too, because\n * whether the export includes this judgment is still to be decided.\n */\nexport function withoutTurnEvaluation(\n messages: UIChatMessage[],\n): UIChatMessage[] {\n return messages.map((message) => {\n if (!message.metadata?.turnEvaluation) {\n return message\n }\n const { turnEvaluation: _turnEvaluation, ...metadata } =\n message.metadata\n return { ...message, metadata }\n })\n}\n\n/**\n * The history without the tool catalogue records, for a reader outside the\n * organization (a public chat read, the data export): a record names every\n * group the agent has, used or not.\n */\nexport function withoutToolCatalogue(\n messages: UIChatMessage[],\n): UIChatMessage[] {\n return messages.map((message) => {\n if (!message.metadata?.toolCatalogue) {\n return message\n }\n const { toolCatalogue: _toolCatalogue, ...metadata } = message.metadata\n return { ...message, metadata }\n })\n}\n\n/**\n * States in which a tool invocation part waits for nothing more.\n *\n * Two readers, one meaning: the backend leaves such a part alone instead of\n * forcing it to a terminal state (`completeUnresolvedToolInvocations`), and the\n * web client counts it as answered when deciding whether to resume a suspended\n * turn (`sendAutomaticallyWhen` in `useChatbotStore`). They used to keep a copy\n * each, with different membership.\n */\nexport const TOOL_TERMINAL_STATES: ReadonlySet<string> = new Set([\n 'output-available',\n 'output-error',\n 'output-denied',\n])\n\nexport const ChatSchema = z.object({\n id: z.string(),\n messages: z.array(z.unknown()) as unknown as z.ZodType<UIChatMessage[]>,\n title: z.string().nullable(),\n summary: z.string().nullable(),\n messageCountAtLastSummary: z.string().nullable(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n metadata: z.record(z.string(), z.unknown()),\n totalCostInUSD: z.string(),\n usage: z.unknown() as unknown as z.ZodType<LanguageModelUsage>,\n agentId: z.string().nullable(),\n userId: z.string(),\n organizationId: z.string(),\n deleted: z.boolean(),\n deletedAt: z.coerce.date().nullable(),\n deletedBy: z.string().nullable(),\n conversationAnalysis: ConversationAnalysisSchema.nullable().optional(),\n blocked: z.boolean(),\n blockedAt: z.coerce.date().nullable(),\n blockedReasonCode: z.enum(BlockedReasonCode).nullable(),\n blockedReason: z.string().nullable(),\n warningCount: z.number(),\n lastMessageAt: z.coerce.date(),\n})\n\nexport const ChatsQuerystringSchema = z.object({\n ...zodQs.pagination(),\n ...zodQs.sort(['updatedAt', 'createdAt', 'lastMessageAt']),\n ...zodQs.filters(['agentId', 'userId']),\n ...zodQs.range('updatedAt'),\n ...zodQs.range('lastMessageAt'),\n ...zodQs.ids(),\n startDate: z.string().optional(),\n endDate: z.string().optional(),\n})\n\nexport const ChatsPublicSchema = z.object({\n id: z.string(),\n agentId: z.string().optional(),\n organizationId: z.string(),\n summary: z.string().optional(),\n title: z.string().optional(),\n userId: z.string(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n lastMessageAt: z.coerce.date(),\n messages: z.array(z.unknown()),\n blocked: z.boolean(),\n})\n\nexport type ChatPublic = z.infer<typeof ChatsPublicSchema>\n","var e=class{constructor(e,t){this.operator=e,this.value=t,Object.defineProperty(this,`_notes`,{writable:!0})}get notes(){return this._notes}addNote(e){this._notes=this._notes||[],this._notes.push(e)}},t=class extends e{},n=class extends t{constructor(e,t){if(!Array.isArray(t))throw Error(`\"${e}\" operator expects to receive an array of conditions`);super(e,t)}};const r=`__itself__`;var i=class extends e{constructor(e,t,n){super(e,n),this.field=t}};const a=new t(`__null__`,null),o=Object.hasOwn||((e,t)=>Object.prototype.hasOwnProperty.call(e,t));function s(e,t){return t instanceof n&&t.operator===e}function c(e,t){let r;for(let i=0,a=t.length;i<a;i++){let a=t[i];if(a instanceof n){if(a.operator!==e){r&&r.push(a);continue}if(a.value.length===0)continue;r||(r=t.slice(0,i));let n=a.value;for(let e=0,t=n.length;e<t;e++)r.push(n[e])}else r&&r.push(a)}return r||t}function l(e,t){if(t.length===1)return t[0];if(t.length===0)return new n(e,t);let r=c(e,t);return r.length===1?r[0]:(r.length,new n(e,r))}const u=e=>e,d=()=>Object.create(null),f=Object.defineProperty(d(),`__@type@__`,{value:`ignore value`});function p(e,t,n=!1){if(!e||e&&e.constructor!==Object)return!1;for(let r in e)if(o(e,r)&&o(t,r)&&(!n||e[r]!==f))return!0;return!1}function m(e){let t=[];for(let n in e)o(e,n)&&e[n]!==f&&t.push(n);return t}function h(e,t){t!==a&&e.push(t)}const g=e=>l(`and`,e),_=e=>l(`or`,e);function v(e,t){let n=e[t];if(typeof n!=`function`)throw Error(`Unable to interpret \"${String(t)}\" condition. Did you forget to register interpreter for it?`);return n}function y(e){return e.operator}function b(e,t){let n=t,r=n&&n.getInterpreterName||y,i;switch(n?n.numberOfArguments:0){case 1:i=(t=>v(e,r(t,n))(t,a));break;case 3:i=((t,i,o)=>v(e,r(t,n))(t,i,o,a));break;default:i=((t,i)=>v(e,r(t,n))(t,i,a));break}let a={...n,interpret:i};return a.interpret}const x={compound(e,t,r){let i=(Array.isArray(t)?t:[t]).map(e=>r.parse(e));return new n(e.name,i)},field(e,t,n){return new i(e.name,n.field,t)},document(e,n){return new t(e.name,n)}};var S=class{constructor(e,t=d()){this.parse=this.parse.bind(this),this._options={operatorToConditionName:t.operatorToConditionName||u,defaultOperatorName:t.defaultOperatorName||`eq`,mergeFinalConditions:t.mergeFinalConditions||g},this._instructions=Object.keys(e).reduce((t,n)=>(t[n]={name:this._options.operatorToConditionName(n),...e[n]},t),{}),this._fieldInstructionContext={...t.fieldContext,field:``,query:{},parse:this.parse,hasOperators:e=>p(e,this._instructions,t.useIgnoreValue)},this._documentInstructionContext={...t.documentContext,parse:this.parse,query:{}},this._objectKeys=t.useIgnoreValue?m:Object.keys}setParse(e){this.parse=e,this._fieldInstructionContext.parse=e,this._documentInstructionContext.parse=e}parseField(e,t,n,r){let i=this._instructions[t];if(!i)throw Error(`Unsupported operator \"${t}\"`);if(i.type!==`field`)throw Error(`Unexpected ${i.type} operator \"${t}\" at field level`);return this._fieldInstructionContext.field=e,this._fieldInstructionContext.query=r,this.parseInstruction(i,n,this._fieldInstructionContext)}parseInstruction(e,t,n){return typeof e.validate==`function`&&e.validate(e,t),(e.parse||x[e.type])(e,t,n)}parseFieldOperators(e,t){let n=[],r=this._objectKeys(t);for(let i=0,a=r.length;i<a;i++){let a=r[i];if(!this._instructions[a])throw Error(`Field query for \"${e}\" may contain only operators or a plain object as a value`);h(n,this.parseField(e,a,t[a],t))}return n}parse(e){let t=[],n=this._objectKeys(e);this._documentInstructionContext.query=e;for(let r=0,i=n.length;r<i;r++){let i=n[r],a=e[i],o=this._instructions[i];if(o){if(o.type!==`document`&&o.type!==`compound`)throw Error(`Cannot use parsing instruction for operator \"${i}\" in \"document\" context as it is supposed to be used in \"${o.type}\" context`);h(t,this.parseInstruction(o,a,this._documentInstructionContext))}else this._fieldInstructionContext.hasOperators(a)?t.push(...this.parseFieldOperators(i,a)):h(t,this.parseField(i,this._options.defaultOperatorName,a,e))}return this._options.mergeFinalConditions(t)}};function C(e,t){return(n,...r)=>{let i=e(n,...r),a=t.bind(null,i);return Object.defineProperty(a,`ast`,{value:i}),a}}export{n as CompoundCondition,e as Condition,t as DocumentCondition,i as FieldCondition,r as ITSELF,a as NULL_CONDITION,S as ObjectQueryParser,g as buildAnd,_ as buildOr,b as createInterpreter,C as createTranslatorFactory,x as defaultInstructionParsers,p as hasOperators,u as identity,f as ignoreValue,s as isCompound,d as object,l as optimizedCompoundCondition};\n//# sourceMappingURL=index.mjs.map","import{CompoundCondition as e,FieldCondition as t,ITSELF as n,NULL_CONDITION as r,ObjectQueryParser as i,buildAnd as a,defaultInstructionParsers as o,optimizedCompoundCondition as s}from\"@ucast/core\";var c=Object.defineProperty,l=((e,t)=>{let n={};for(var r in e)c(n,r,{get:e[r],enumerable:!0});return t||c(n,Symbol.toStringTag,{value:`Module`}),n})({$all:()=>y,$and:()=>u,$elemMatch:()=>h,$eq:()=>E,$exists:()=>x,$gt:()=>C,$gte:()=>S,$in:()=>_,$lt:()=>w,$lte:()=>T,$mod:()=>b,$ne:()=>D,$nin:()=>v,$nor:()=>f,$not:()=>m,$options:()=>k,$or:()=>d,$regex:()=>O,$size:()=>g,$where:()=>A});const u={type:`compound`,validate:M,parse(e,t,n){let r=p(e,t,n);return s(e.name,r)}},d=u,f={type:`compound`,validate:M,parse(t,n,r){let i=p(t,n,r);return new e(t.name,i)}};function p(e,t,n){let r=Array(t.length);for(let i=0;i<t.length;i++){let a=t[i];F(e,a,i),r[i]=n.parse(a)}return r}const m={type:`field`,validate(e,t){if(!(t&&(t instanceof RegExp||t.constructor===Object)))throw Error(`\"${e.name}\" expects to receive either regular expression or object of field operators`)},parse(n,r,i){let a=r instanceof RegExp?new t(`regex`,i.field,r):i.parse(r,i);return new e(n.name,[a])}},h={type:`field`,validate(e,t){if(!t||t.constructor!==Object)throw Error(`\"${e.name}\" expects to receive an object with nested query or field level operators`)},parse(e,r,{parse:i,field:a,hasOperators:o}){let s=o(r)?i(r,{field:n}):i(r);return new t(e.name,a,s)}},g={type:`field`,validate:P(`number`)},_={type:`field`,validate:j},v=_,y=_,b={type:`field`,validate(e,t){if(!Array.isArray(t)||t.length!==2)throw Error(`\"${e.name}\" expects an array with 2 numeric elements`)}},x={type:`field`,validate:P(`boolean`)},S={type:`field`,validate:N},C=S,w=C,T=C,E={type:`field`},D=E,O={type:`field`,validate(e,t){if(!(t instanceof RegExp)&&typeof t!=`string`)throw Error(`\"${e.name}\" expects value to be a regular expression or a string that represents regular expression`)},parse(e,n,r){let i=typeof n==`string`?new RegExp(n,r.query.$options||``):n;return new t(e.name,r.field,i)}},k={type:`field`,parse:()=>r},A={type:`document`,validate:P(`function`)};function j(e,t){if(!Array.isArray(t))throw Error(`\"${e.name}\" expects value to be an array`)}function M(e,t){if(j(e,t),!t.length)throw Error(`\"${e.name}\" expects to have at least one element in array`)}function N(e,t){if(!(typeof t==`string`||typeof t==`number`||t instanceof Date))throw Error(`\"${e.name}\" expects value to be comparable (i.e., string, number or date)`)}function P(e){return(t,n)=>{if(typeof n!==e)throw Error(`\"${t.name}\" expects value to be a \"${e}\"`)}}function F(e,t,n){let r=t;if(!r||r.constructor!==Object)throw Error(`\"${e.name}\" expects item at index ${n} to be an object`)}var I=class extends i{constructor(e){super(e,{defaultOperatorName:`$eq`,operatorToConditionName:e=>e.slice(1)})}parse(e,t){return t&&t.field?a(this.parseFieldOperators(t.field,e)):super.parse(e)}};const L=l;export{y as $all,u as $and,h as $elemMatch,E as $eq,x as $exists,C as $gt,S as $gte,_ as $in,w as $lt,T as $lte,b as $mod,D as $ne,v as $nin,f as $nor,m as $not,k as $options,d as $or,O as $regex,g as $size,A as $where,I as MongoQueryParser,L as allParsingInstructions,o as defaultParsers};\n//# sourceMappingURL=index.mjs.map","import type { MongoQuery } from '@ucast/mongo2js'\n\n// Minimal structural shape of the better-auth session consumed here.\n// Declared locally to avoid a workspace dependency cycle with `auth`\n// (auth depends on `ability` for its access-control config).\n// The full `auth` Session is structurally assignable to this type.\nexport type Session = {\n session: {\n activeOrganizationId?: string | null\n organizationRole?: string | null\n }\n user: {\n id?: string\n role?: string | null\n }\n}\n\nexport enum Audience {\n Backoffice = 'backoffice',\n Frontoffice = 'frontoffice',\n System = 'system',\n Public = 'public',\n}\n\nexport enum Subject {\n All = 'all',\n Todo = 'todo',\n User = 'user',\n Chat = 'chat',\n Agent = 'agent',\n SubAgent = 'subAgent',\n Document = 'document',\n AgentDocument = 'agent_document',\n AgentAnalytic = 'agent_analytic',\n McpServer = 'mcp_server',\n Media = 'media',\n RevisedAnswer = 'revised_answer',\n Organization = 'organization',\n Member = 'member',\n Lead = 'lead',\n MessageFeedback = 'message_feedback',\n Backoffice = 'backoffice',\n Frontoffice = 'frontoffice',\n System = 'system',\n Invitation = 'invitation',\n Crawler = 'crawler',\n ReasoningChat = 'reasoning_chat',\n OrganizationExternalAuth = 'organization_external_auth',\n AgentEndpoint = 'agent_endpoint',\n AgentEndpointLog = 'agent_endpoint_log',\n AgentApiTool = 'agent_api_tool',\n DocumentFolder = 'document_folder',\n Integration = 'integration',\n Notification = 'notification',\n PlatformConnection = 'platform_connection',\n}\n\n// action\nexport type Action =\n | 'create'\n | 'read'\n | 'update'\n | 'delete'\n | 'manage'\n | 'impersonate'\n | 'invite'\n | 'access'\n | 'clone'\n | 'ban'\n | 'unban'\n | 'change-role'\n | 'resend'\n | 'cancel'\n | 'execute'\n | 'refill'\n\nexport type Capability = {\n action: Action\n subject: Subject\n fields?: string[]\n condition?: MongoQuery\n inverted?: boolean\n}\n\nexport type CapabilitiesFactory = (\n currentSession?: Session | null,\n) => Capability[]\n","import type {\n MongoAbility,\n InferSubjects,\n ForcedSubject,\n FieldMatcher,\n} from '@casl/ability'\nimport type { Action, Capability, Subject } from './types'\nimport { type Session } from './types'\nimport { $or } from '@ucast/mongo2js'\nimport {\n AbilityBuilder,\n createMongoAbility,\n buildMongoQueryMatcher,\n createAliasResolver,\n subject as caslSubject,\n} from '@casl/ability'\nimport { organizationCapabilitiesByRole, userCapabilitiesByRole } from './roles'\nimport DefaultCapabilities from './roles/User'\nimport { createAccessControl } from 'better-auth/plugins'\nimport {\n adminAc,\n defaultStatements,\n memberAc,\n ownerAc,\n} from 'better-auth/plugins/organization/access'\n\nexport const OrganizationRoles = {\n admin: 'admin',\n owner: 'owner',\n member: 'member',\n user: 'user',\n} as const\n\nexport const UserRoles = {\n admin: 'admin',\n user: 'user',\n} as const\n\n// action alias\nconst resolveAction = createAliasResolver({\n modify: ['read', 'update', 'delete'],\n})\n\n// subject\nexport type AbilitySubject =\n | InferSubjects<'all' | Subject, true>\n | ForcedSubject<InferSubjects<'all' | Subject, true>>\nexport type AppAbility = MongoAbility<[Action, AbilitySubject]>\n\n// matcher\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst conditionsMatcher = buildMongoQueryMatcher({ $or } as Record<string, any>)\nconst fieldMatcher: FieldMatcher = (fields) => (field) => fields.includes(field)\n\nexport const isValidOrganizationRole = (\n role?: string | null,\n): role is keyof typeof OrganizationRoles => {\n if (!role) {\n return false\n }\n return role in OrganizationRoles\n}\n\nexport const isValidUserRole = (\n role?: string | null,\n): role is keyof typeof UserRoles => {\n if (!role) {\n return false\n }\n return role in UserRoles\n}\n\nexport const getOrganizationRoleCapabilities = (\n currentSession?: Session | null,\n): Capability[] => {\n const organizationRole = currentSession?.session?.organizationRole\n if (!isValidOrganizationRole(organizationRole)) {\n return DefaultCapabilities(currentSession)\n }\n const capabilities = organizationCapabilitiesByRole[organizationRole]\n if (typeof capabilities === 'function') {\n return capabilities(currentSession)\n }\n return capabilities\n}\n\nexport const getUserRoleCapabilities = (\n currentSession?: Session | null,\n): Capability[] => {\n const userRole = currentSession?.user?.role\n if (!isValidUserRole(userRole)) {\n return DefaultCapabilities(currentSession)\n }\n const capabilities = userCapabilitiesByRole[userRole]\n if (typeof capabilities === 'function') {\n return capabilities(currentSession)\n }\n return capabilities\n}\n\n/**\n * Builds the ability of one caller: the session's roles, or the guest rules\n * when there is no session. Every call returns a new instance and this package\n * keeps none: a server judges many callers at once, so an instance shared\n * between them is judged by whoever wrote it last. The backend builds one per\n * request (`request.ability`), the Platform MCP one per tool call, and the\n * frontend keeps its own for the single user of the tab.\n */\nexport const buildAbilityForSession = (\n currentSession?: Session | null,\n): AppAbility => {\n const { can, build, cannot } = new AbilityBuilder<AppAbility>(\n createMongoAbility,\n )\n const organizationRoleCapabilities =\n getOrganizationRoleCapabilities(currentSession)\n const userRoleCapabilities = getUserRoleCapabilities(currentSession)\n const capabilities = [\n ...organizationRoleCapabilities,\n ...userRoleCapabilities,\n ]\n capabilities.forEach((capability) => {\n const { action, subject, fields, condition, inverted } = capability\n if (inverted) {\n cannot(action, subject, fields, condition)\n return\n }\n can(action, subject, fields, condition)\n })\n return build({\n conditionsMatcher,\n resolveAction,\n fieldMatcher,\n })\n}\n\nexport type PermissionMap = Partial<Record<Action, Subject>>\n\nconst isEmptyObject = (value: unknown) =>\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0\n\n/**\n * Evaluates a route-style permission map ({ action: Subject }) against an\n * ability instance. When `payload` is provided it is bound as subject\n * conditions, same as the HTTP route preHandler does with `request.body`.\n * An empty object is checked like a missing payload: it says nothing about\n * the resource, and as a subject it has no field for a rule's conditions to\n * match, so a client that sent `{}` to a route taking no body (activate,\n * deactivate) was refused what the same request without a body got.\n * Returns the first denied pair, or null when every check passes.\n * Single source of truth for both the HTTP preHandler and the Platform MCP\n * tool handlers.\n */\nexport const findDeniedPermission = (\n abilityInstance: Pick<AppAbility, 'can'>,\n permissions: PermissionMap,\n payload?: unknown,\n): { action: Action; subject: Subject } | null => {\n let action: Action\n for (action in permissions) {\n const actionSubject = permissions[action]\n if (!actionSubject) {\n continue\n }\n const target =\n payload && !isEmptyObject(payload)\n ? caslSubject(\n actionSubject,\n payload as Record<PropertyKey, unknown>,\n )\n : actionSubject\n if (!abilityInstance.can(action, target)) {\n return { action, subject: actionSubject }\n }\n }\n return null\n}\n\nconst ac = createAccessControl(defaultStatements)\nconst adminRole = ac.newRole(adminAc.statements)\nconst ownerRole = ac.newRole(ownerAc.statements)\nconst memberRole = ac.newRole(memberAc.statements)\nconst userRole = ac.newRole(memberAc.statements)\n\nexport const betterAuthOrganizationSettings = {\n ac,\n roles: {\n owner: ownerRole,\n admin: adminRole,\n member: memberRole,\n user: userRole,\n },\n}\n\n/**\n * Whether a user is currently banned. A ban with no expiry is permanent, one\n * with an expiry in the future is still in force, one already elapsed is not.\n * Every admission path (API key, Platform MCP, voice callback) must apply the\n * same rule: a ban that holds in one path and not another is a hole.\n */\nexport const isUserBanned = (\n user:\n | { banned?: boolean | null; banExpires?: Date | null }\n | null\n | undefined,\n): boolean =>\n user?.banned === true &&\n (user.banExpires === null ||\n user.banExpires === undefined ||\n user.banExpires > new Date())\n\nexport * from './types'\nexport { subject } from '@casl/ability'\n","import { removeTrailingSlash } from 'utils'\n\nexport interface ResolveShortUrlsOptions {\n /** Extra headers to send (e.g. auth). */\n headers?: Record<string, string>\n /** Fetch credentials mode. Defaults to `'include'`. */\n credentials?: RequestCredentials\n}\n\n/**\n * Single implementation of the short-url batch resolve used across apps\n * (chatbot api client, frontend app root). Maps `/api/r/<hash>` short urls back\n * to their real target via `POST <backend>/api/r/resolve`.\n *\n * The redirect endpoint lives at `/api/r`, outside the JSON:API basePath, and\n * is unauthenticated. Returns an empty map (short urls left untouched) on any\n * failure so callers never have to handle errors.\n */\nexport async function resolveShortUrls(\n backendUrl: string,\n hashes: string[],\n options: ResolveShortUrlsOptions = {},\n): Promise<Record<string, string>> {\n try {\n const root = removeTrailingSlash(backendUrl)\n const response = await fetch(`${root}/api/r/resolve`, {\n method: 'POST',\n credentials: options.credentials ?? 'include',\n headers: {\n ...options.headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ hashes }),\n })\n if (!response.ok) {\n return {}\n }\n const data = (await response.json()) as {\n urls?: Record<string, string>\n }\n return data.urls ?? {}\n } catch {\n return {}\n }\n}\n","import { Audience } from 'ability'\nimport { ChatSchema, ChatsPublicSchema, VoiceSessionSchema } from 'models'\nimport type {\n AgentAccess,\n Chat,\n ChatWakeupState,\n DeviceContext,\n MessageFeedback,\n AgentPublic,\n MediaSource,\n VoiceSession,\n} from 'models'\nimport { addInitialSlash, removeTrailingSlash } from 'utils'\nimport { resolveShortUrls as resolveShortUrlsRequest } from './resolveShortUrls'\n\n// The chats endpoints respond with the full shape (frontoffice) or the\n// trimmed public one — same union the backend declares. Parsing coerces the\n// date fields (plain JSON strings otherwise); on mismatch keep the raw\n// payload instead of failing.\nconst ConversationSchema = ChatSchema.or(ChatsPublicSchema)\nfunction parseConversation(raw: unknown): Chat {\n const result = ConversationSchema.safeParse(raw)\n return (result.success ? result.data : raw) as Chat\n}\n\n/**\n * What went wrong, in words, from the problem+json the backend answers with\n * (`{ type, title, status, message }`). Falling straight back to the status\n * produced \"API error: 409\" on screen, which tells the reader nothing and hides\n * a message that was already there and already explains the fix.\n */\nasync function readErrorMessage(response: Response): Promise<string> {\n const fallback = `${response.status} ${response.statusText}`.trim()\n try {\n const body = (await response.json()) as {\n message?: string\n title?: string\n }\n return body.message?.trim() || body.title?.trim() || fallback\n } catch {\n return fallback\n }\n}\n\nexport interface ChatbotApiClientOptions {\n baseUrl: string\n basePath?: string\n headers?: () => Record<string, string> | undefined\n credentials?: RequestCredentials\n}\n\nexport interface SubmitFeedbackPayload {\n messageId: string\n chatId: string\n agentId: string\n vote?: 'upvote' | 'downvote'\n userQuestion: string\n assistantMessage: string\n comment?: string\n}\n\nexport interface SubmitLeadPayload {\n agentId: string\n chatId: string\n [key: string]: unknown\n}\n\n/** A file from the user's \"My files\" KB, or a spreadsheet of the chat with its\n * versions, as listed for a chat. */\nexport interface ChatbotFile {\n documentId: string\n kind: 'document' | 'spreadsheet'\n /** For a spreadsheet version, the attachment it is a version of. */\n sourceAttachmentId: string | null\n name: string | null\n mimeType: string | null\n indexStatus: string\n createdAt: string\n}\n\nexport interface ChatbotApiClient {\n getConversations(\n agentId: string,\n userId: string | undefined,\n ): Promise<Chat[]>\n getChat(agentId: string, chatId: string): Promise<Chat | null>\n /** The wakeup still waiting in a chat (spec agent-wakeup). */\n getChatWakeup(agentId: string, chatId: string): Promise<ChatWakeupState>\n /** The user's \"Stop\" of the chat's pending wakeup. */\n stopChatWakeup(agentId: string, chatId: string): Promise<ChatWakeupState>\n /** The chat is open in a visible tab: its wakeups mail nothing meanwhile. */\n markChatWakeupPresence(agentId: string, chatId: string): Promise<void>\n updateChatTitle(\n agentId: string,\n chatId: string,\n title: string,\n ): Promise<Chat>\n deleteChat(agentId: string, chatId: string): Promise<void>\n getMessageFeedbacks(chatId: string): Promise<MessageFeedback[]>\n submitMessageFeedback(\n payload: SubmitFeedbackPayload,\n ): Promise<MessageFeedback>\n submitLead(payload: SubmitLeadPayload): Promise<void>\n getAgent(orgSlug: string, agentId: string): Promise<AgentPublic>\n getAgentAccess(orgSlug: string, agentId: string): Promise<AgentAccess>\n getMediaUrl(agentId: string, chatId: string, storedFileName: string): string\n /** Like {@link getMediaUrl}, served as an attachment: the browser saves it. */\n getMediaDownloadUrl(\n agentId: string,\n chatId: string,\n storedFileName: string,\n ): string\n appendAuthToken(url: string): string\n uploadMedia(\n agentId: string,\n chatId: string,\n file: File,\n ): Promise<MediaSource>\n getChatEndpoint(agentId: string, type?: 'chat' | 'reasoning'): string\n expandSourceContext(\n agentId: string,\n documentId: string,\n chunkIndex: number,\n windowSize?: number,\n ): Promise<{ content: string }>\n downloadSourceDocument(\n agentId: string,\n documentId: string,\n ): Promise<{ downloadUrl: string; filename: string; mimeType: string }>\n reverseGeocode(\n lat: number,\n lon: number,\n lang?: string,\n ): Promise<string | undefined>\n forwardGeocode(\n query: string,\n lang?: string,\n ): Promise<\n { latitude: number; longitude: number; displayName: string } | undefined\n >\n getOAuthAuthorizeUrl(\n agentId: string,\n serverName: string,\n ): Promise<{ mcpServerId: string; authorizeUrl: string }>\n getOAuthConnectionStatus(\n agentId: string,\n serverName: string,\n ): Promise<{ mcpServerId: string; connected: boolean }>\n resolveShortUrls(hashes: string[]): Promise<Record<string, string>>\n getChatFiles(chatId: string): Promise<ChatbotFile[]>\n getChatFileDownloadUrl(documentId: string, inline?: boolean): string\n getChatFilePreviewUrl(documentId: string): string\n deleteChatFile(documentId: string): Promise<void>\n createVoiceSession(\n agentId: string,\n chatId?: string,\n /**\n * Everything the call inherits from the page it starts on. Sent once,\n * because the spoken turns arrive from the voice provider and carry\n * none of it.\n */\n context?: {\n deviceContext?: DeviceContext\n externalContext?: Record<string, unknown>\n },\n ): Promise<VoiceSession>\n closeVoiceSession(agentId: string, sessionId: string): Promise<void>\n}\n\nexport function createChatbotApiClient(\n options: ChatbotApiClientOptions,\n): ChatbotApiClient {\n const basePath = options.basePath\n ? addInitialSlash(options.basePath)\n : `/api/v1/${Audience.Public}`\n\n const baseUrl = `${removeTrailingSlash(options.baseUrl)}${basePath}`\n\n // \"My files\" lives under the frontoffice audience, not the agent's base\n // (which may be public, backoffice, …) — derive it by swapping the trailing\n // audience segment of basePath for `frontoffice`.\n const frontofficeBase = `${removeTrailingSlash(options.baseUrl)}${basePath.replace(\n /\\/[^/]+$/,\n `/${Audience.Frontoffice}`,\n )}`\n\n async function request<T>(\n url: string,\n init?: RequestInit,\n responseType: 'json' | 'void' = 'json',\n ): Promise<T> {\n const response = await fetch(`${baseUrl}${url}`, {\n credentials: options.credentials ?? 'include',\n ...init,\n headers: {\n ...options.headers?.(),\n ...init?.headers,\n },\n })\n\n if (!response.ok) {\n throw new Error(await readErrorMessage(response))\n }\n\n if (responseType === 'void' || response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n }\n\n return {\n async getConversations(agentId, userId) {\n const userFilter = userId\n ? `&filter[userId]=${encodeURIComponent(userId)}`\n : ''\n const conversations = await request<unknown[]>(\n `/agents/${encodeURIComponent(agentId)}/chats?sort=-lastMessageAt&page[size]=100${userFilter}`,\n )\n return conversations.map(parseConversation)\n },\n\n async getChatFiles(chatId) {\n const response = await fetch(\n `${frontofficeBase}/me/documents?filter[chatId]=${encodeURIComponent(chatId)}&page[size]=100`,\n {\n credentials: options.credentials ?? 'include',\n headers: { ...options.headers?.() },\n },\n )\n if (!response.ok) {\n throw new Error(\n `API error: ${response.status} ${response.statusText}`,\n )\n }\n return (await response.json()) as ChatbotFile[]\n },\n\n getChatFileDownloadUrl(documentId, inline) {\n const suffix = inline ? '?inline=true' : ''\n // appendAuthToken carries a bearer in the query so <img>/<a>\n // subresources (which can't set an Authorization header) authorize\n // cross-origin in the embedded widget; no-op for cookie auth.\n return this.appendAuthToken(\n `${frontofficeBase}/me/documents/${encodeURIComponent(documentId)}/download${suffix}`,\n )\n },\n\n getChatFilePreviewUrl(documentId) {\n // Small resized preview blob for row thumbnails (see download\n // endpoint ?preview=true); auth token carried for cross-origin <img>.\n return this.appendAuthToken(\n `${frontofficeBase}/me/documents/${encodeURIComponent(documentId)}/download?preview=true`,\n )\n },\n\n async deleteChatFile(documentId) {\n const response = await fetch(\n `${frontofficeBase}/me/documents/${encodeURIComponent(documentId)}`,\n {\n method: 'DELETE',\n credentials: options.credentials ?? 'include',\n headers: { ...options.headers?.() },\n },\n )\n if (!response.ok) {\n throw new Error(\n `API error: ${response.status} ${response.statusText}`,\n )\n }\n },\n\n async getChat(agentId, chatId) {\n const result = await request<Chat | undefined>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}`,\n )\n return result ? parseConversation(result) : null\n },\n\n async getChatWakeup(agentId, chatId) {\n return request<ChatWakeupState>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/wakeup`,\n )\n },\n\n async stopChatWakeup(agentId, chatId) {\n return request<ChatWakeupState>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/wakeup`,\n { method: 'DELETE' },\n )\n },\n\n async markChatWakeupPresence(agentId, chatId) {\n await request<void>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/wakeup/presence`,\n { method: 'PUT' },\n 'void',\n )\n },\n\n async updateChatTitle(agentId, chatId, title) {\n return parseConversation(\n await request<Chat>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}`,\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title }),\n },\n ),\n )\n },\n\n async deleteChat(agentId, chatId) {\n await request<void>(\n `/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}`,\n { method: 'DELETE' },\n 'void',\n )\n },\n\n async getMessageFeedbacks(chatId) {\n return request<MessageFeedback[]>(\n `/message-feedbacks?filter[chatId]=${encodeURIComponent(chatId)}&page[size]=200`,\n )\n },\n\n async submitMessageFeedback(payload) {\n return request<MessageFeedback>('/message-feedbacks', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n })\n },\n\n async submitLead(payload) {\n await request<void>(\n '/leads',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n 'void',\n )\n },\n\n async getAgent(orgSlug, agentId) {\n return request<AgentPublic>(\n `/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}`,\n )\n },\n\n async getAgentAccess(orgSlug, agentId) {\n return request<AgentAccess>(\n `/organizations/${encodeURIComponent(orgSlug)}/agents/${encodeURIComponent(agentId)}/access`,\n )\n },\n\n async uploadMedia(agentId, chatId, file) {\n const formData = new FormData()\n formData.append('file', file)\n const response = await fetch(\n `${baseUrl}/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/media/upload`,\n {\n method: 'POST',\n credentials: options.credentials ?? 'include',\n // Do NOT set Content-Type — browser sets multipart/form-data with boundary automatically\n headers: options.headers?.(),\n body: formData,\n },\n )\n if (!response.ok) {\n const text = await response.text().catch(() => '')\n let title = `Upload failed: ${response.status}`\n try {\n title =\n (JSON.parse(text) as { title?: string }).title ?? title\n } catch {\n // ignore parse errors\n }\n throw new Error(title)\n }\n return response.json() as Promise<MediaSource>\n },\n\n getChatEndpoint(agentId, type = 'chat') {\n const path = type === 'reasoning' ? 'reasoning-chat' : 'chat'\n return `${baseUrl}/agents/${encodeURIComponent(agentId)}/${path}`\n },\n\n appendAuthToken(url) {\n const bearer = options\n .headers?.()\n ?.[`Authorization`]?.slice('Bearer '.length)\n if (!bearer) {\n return url\n }\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}token=${encodeURIComponent(bearer)}`\n },\n\n getMediaUrl(agentId, chatId, storedFileName) {\n const base = `${baseUrl}/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/media/${encodeURIComponent(storedFileName)}/view`\n return this.appendAuthToken(base)\n },\n\n getMediaDownloadUrl(agentId, chatId, storedFileName) {\n const base = `${baseUrl}/agents/${encodeURIComponent(agentId)}/chats/${encodeURIComponent(chatId)}/media/${encodeURIComponent(storedFileName)}/download`\n return this.appendAuthToken(base)\n },\n\n async expandSourceContext(\n agentId,\n documentId,\n chunkIndex,\n windowSize = 2,\n ) {\n return request<{ content: string }>(\n `/agents/${encodeURIComponent(agentId)}/sources/expand-context`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n documentId,\n chunkIndex,\n windowSize,\n }),\n },\n )\n },\n\n async downloadSourceDocument(agentId, documentId) {\n return request<{\n downloadUrl: string\n filename: string\n mimeType: string\n }>(\n `/agents/${encodeURIComponent(agentId)}/sources/documents/${encodeURIComponent(documentId)}/download`,\n )\n },\n\n async reverseGeocode(lat, lon, lang) {\n const params = new URLSearchParams({\n lat: String(lat),\n lon: String(lon),\n })\n if (lang) {\n params.set('lang', lang)\n }\n try {\n const data = await request<{ displayName?: string }>(\n `/geocoder/reverse?${params}`,\n )\n return data.displayName\n } catch {\n return undefined\n }\n },\n\n async forwardGeocode(query, lang) {\n const params = new URLSearchParams({ q: query })\n if (lang) {\n params.set('lang', lang)\n }\n try {\n return await request<{\n latitude: number\n longitude: number\n displayName: string\n }>(`/geocoder/forward?${params}`)\n } catch {\n return undefined\n }\n },\n\n async getOAuthAuthorizeUrl(agentId, serverName) {\n const params = new URLSearchParams({ serverName })\n return request<{ mcpServerId: string; authorizeUrl: string }>(\n `/agents/${encodeURIComponent(agentId)}/mcp-oauth/authorize?${params}`,\n )\n },\n\n async getOAuthConnectionStatus(agentId, serverName) {\n const params = new URLSearchParams({ serverName })\n return request<{ mcpServerId: string; connected: boolean }>(\n `/agents/${encodeURIComponent(agentId)}/mcp-oauth/status?${params}`,\n )\n },\n\n /**\n * Opens a voice session on the conversation currently on screen, so the\n * spoken turns land in the same thread the user can keep typing into.\n * The signed URL it returns is short-lived and per session: the provider\n * credential stays on the server.\n */\n async createVoiceSession(agentId, chatId, context) {\n return VoiceSessionSchema.parse(\n await request<unknown>(\n `/agents/${encodeURIComponent(agentId)}/voice/session`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n ...(chatId ? { chatId } : {}),\n // Sent once for the whole call: the spoken turns\n // come from the provider and carry nothing about\n // this browser nor about the page it runs on.\n ...(context?.deviceContext\n ? { deviceContext: context.deviceContext }\n : {}),\n ...(context?.externalContext\n ? { externalContext: context.externalContext }\n : {}),\n }),\n },\n ),\n )\n },\n\n /**\n * `keepalive` on purpose: this is the call that settles the minutes of a\n * session, and it is often made while the page is going away (hang up on\n * unload, tab closed). Without it the browser is free to cancel it.\n */\n async closeVoiceSession(agentId, sessionId) {\n await request<void>(\n `/agents/${encodeURIComponent(agentId)}/voice/session/${encodeURIComponent(sessionId)}`,\n { method: 'DELETE', keepalive: true },\n 'void',\n )\n },\n\n resolveShortUrls(hashes) {\n return resolveShortUrlsRequest(options.baseUrl, hashes, {\n headers: options.headers?.(),\n credentials: options.credentials,\n })\n },\n }\n}\n"],"ignoreList":[2,3],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import "./src-DCfvejyT.js";
1
+ import "./src-DpkuiHam.js";
2
2
  import { i as e } from "./url-validation-9DstIfq2.js";
3
3
  function t(t, n, r) {
4
4
  return t.data?.type === "mcp-oauth-complete" && !!n && t.source === n && t.origin === e(r);
@@ -6,4 +6,4 @@ function t(t, n, r) {
6
6
  //#endregion
7
7
  export { t };
8
8
 
9
- //# sourceMappingURL=mcpOAuthReport-BeZDTl87.js.map
9
+ //# sourceMappingURL=mcpOAuthReport-3A9v_gW_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcpOAuthReport-BeZDTl87.js","names":["urlOrigin","isMcpOAuthReport","event","signInWindow","backendUrl"],"sources":["../../../../packages/components/src/chat/mcpOAuthReport.ts"],"sourcesContent":["import { urlOrigin } from 'utils'\n\n/** The `type` the MCP sign-in callback page posts (mcpOAuth.controller.ts). */\nexport const MCP_OAUTH_REPORT_TYPE = 'mcp-oauth-complete'\n\n/**\n * Whether a `message` event is the report of the MCP sign-in a page opened:\n * posted by that window while it shows the callback page, which runs on the\n * backend's origin. Any other window holding the page could post the same\n * message, success included, and so could the provider's own pages, which run\n * in that same window before the callback. Without the window or the backend\n * URL nothing is a report, and the caller relies on reading the connection.\n */\nexport function isMcpOAuthReport(\n event: MessageEvent,\n signInWindow: Window | null | undefined,\n backendUrl: string | undefined,\n): boolean {\n return (\n event.data?.type === MCP_OAUTH_REPORT_TYPE &&\n !!signInWindow &&\n event.source === signInWindow &&\n event.origin === urlOrigin(backendUrl)\n )\n}\n"],"mappings":";;AAaA,SAAgBC,EACZ,GACA,GACA,GACO;CACP,OACIC,EAAM,MAAM,SAAA,wBACZ,CAAC,CAACC,KACFD,EAAM,WAAWC,KACjBD,EAAM,WAAWF,EAAUI,CAAU;AAE7C"}
1
+ {"version":3,"file":"mcpOAuthReport-3A9v_gW_.js","names":["urlOrigin","isMcpOAuthReport","event","signInWindow","backendUrl"],"sources":["../../../../packages/components/src/chat/mcpOAuthReport.ts"],"sourcesContent":["import { urlOrigin } from 'utils'\n\n/** The `type` the MCP sign-in callback page posts (mcpOAuth.controller.ts). */\nexport const MCP_OAUTH_REPORT_TYPE = 'mcp-oauth-complete'\n\n/**\n * Whether a `message` event is the report of the MCP sign-in a page opened:\n * posted by that window while it shows the callback page, which runs on the\n * backend's origin. Any other window holding the page could post the same\n * message, success included, and so could the provider's own pages, which run\n * in that same window before the callback. Without the window or the backend\n * URL nothing is a report, and the caller relies on reading the connection.\n */\nexport function isMcpOAuthReport(\n event: MessageEvent,\n signInWindow: Window | null | undefined,\n backendUrl: string | undefined,\n): boolean {\n return (\n event.data?.type === MCP_OAUTH_REPORT_TYPE &&\n !!signInWindow &&\n event.source === signInWindow &&\n event.origin === urlOrigin(backendUrl)\n )\n}\n"],"mappings":";;AAaA,SAAgBC,EACZ,GACA,GACA,GACO;CACP,OACIC,EAAM,MAAM,SAAA,wBACZ,CAAC,CAACC,KACFD,EAAM,WAAWC,KACjBD,EAAM,WAAWF,EAAUI,CAAU;AAE7C"}
@@ -80,8 +80,8 @@ var e = null, t = /pass(word)?|secret|token|api[-_]?key|authorization|cookie|cre
80
80
  l && console.timeLog(e, ...t);
81
81
  }
82
82
  };
83
- new TextEncoder();
83
+ new TextEncoder(), new Set("20 27 30 31 32 33 34 36 39 40 41 43 44 45 46 47 48 49 51 52 53 54 55 56 57 58 60 61 62 63 64 65 66 81 82 84 86 90 91 92 93 94 95 98".split(" "));
84
84
  //#endregion
85
85
  export { y as t };
86
86
 
87
- //# sourceMappingURL=src-DCfvejyT.js.map
87
+ //# sourceMappingURL=src-DpkuiHam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-DpkuiHam.js","names":["_otelBridge","SENSITIVE_KEY_RE","SERIALIZE_MAX_DEPTH","SERIALIZE_MAX_LENGTH","safeSerialize","seen","render","val","depth","item","out","key","rendered","value","text","formatParam","param","extractError","params","p","formatParams","isServerSide","isLoggingEnabled","LEVEL_WEIGHT","_consoleFloor","level","printsAt","log","error","err","info","debug","warn","withAttrs","attrs","message","logger","name","condition","table"],"sources":["../../../../packages/utils/src/logger.ts","../../../../packages/utils/src/internal-signature.ts","../../../../packages/utils/src/phoneNumber.ts"],"sourcesContent":["import type { Ref } from 'vue'\n\ntype ExceptionTracker = (\n error: Error,\n properties?: Record<string, string>,\n) => void\n\ntype OtelLoggerBridge = {\n logInfo: (msg: string, attrs?: Record<string, unknown>) => void\n logEvent: (name: string, attrs?: Record<string, unknown>) => void\n logDebug: (msg: string, attrs?: Record<string, unknown>) => void\n logWarn: (msg: string, attrs?: Record<string, unknown>) => void\n logError: (msg: string, attrs?: Record<string, unknown>) => void\n logException: (error: Error, attrs?: Record<string, unknown>) => void\n} | null\n\nlet _exceptionTracker: ExceptionTracker | undefined\n/** Runtime-set bridge to OTel LoggerProvider (set during backend init) */\nlet _otelBridge: OtelLoggerBridge = null\n\n/**\n * Registers the OTel logger bridge at runtime.\n * Called by the backend during startup; no-op in the frontend.\n */\nexport const setOtelLoggerBridge = (bridge: OtelLoggerBridge) => {\n _otelBridge = bridge\n}\n\n/**\n * Registers a callback invoked by error/warn/logError/logWarn to track exceptions\n * (e.g. OTel recordException + span status ERROR).\n */\nexport const setExceptionTracker = (tracker: ExceptionTracker) => {\n _exceptionTracker = tracker\n}\n\n/**\n * Keys whose values must never land in a log line. The OTel sink additionally\n * masks value patterns (see packages/telemetry/src/sanitization.ts), which\n * utils cannot import: the bridge exists precisely to avoid that dependency.\n */\nconst SENSITIVE_KEY_RE =\n /pass(word)?|secret|token|api[-_]?key|authorization|cookie|credential/i\nconst SERIALIZE_MAX_DEPTH = 3\nconst SERIALIZE_MAX_LENGTH = 2_000\n\n/**\n * Serializes a non-Error object for a log line. `String(param)` produced\n * `[object Object]`, which made whole error families undiagnosable. A naked\n * JSON.stringify is not the fix either: it throws on circular references and\n * BigInt, has no depth or length cap, and would promote sensitive fields\n * into the message. This handles all four.\n */\nconst safeSerialize = (value: unknown): string => {\n const seen = new WeakSet<object>()\n const render = (val: unknown, depth: number): unknown => {\n if (val instanceof Error) {\n return val.stack ?? val.message\n }\n if (typeof val === 'bigint') {\n return `${val.toString()}n`\n }\n if (typeof val === 'function' || typeof val === 'symbol') {\n return String(val)\n }\n if (typeof val !== 'object' || val === null) {\n return val\n }\n if (seen.has(val)) {\n return '[Circular]'\n }\n if (depth >= SERIALIZE_MAX_DEPTH) {\n return Array.isArray(val) ? '[Array]' : '[Object]'\n }\n // Added on the way down, removed on the way back up: only a true\n // cycle is flagged, a shared reference (the same object under two\n // keys) is rendered normally.\n seen.add(val)\n try {\n if (Array.isArray(val)) {\n return val.map((item) => render(item, depth + 1))\n }\n const out: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(val)) {\n out[key] = SENSITIVE_KEY_RE.test(key)\n ? '[REDACTED]'\n : render(item, depth + 1)\n }\n return out\n } finally {\n seen.delete(val)\n }\n }\n try {\n const rendered = render(value, 0)\n const text =\n typeof rendered === 'string' ? rendered : JSON.stringify(rendered)\n if (typeof text !== 'string') {\n return String(text)\n }\n return text.length > SERIALIZE_MAX_LENGTH\n ? `${text.slice(0, SERIALIZE_MAX_LENGTH)}… [truncated]`\n : text\n } catch {\n return '[Unserializable]'\n }\n}\n\nconst formatParam = (param: unknown): string => {\n if (param instanceof Error) {\n return param.stack ?? param.message\n }\n if (typeof param === 'object' && param !== null) {\n return safeSerialize(param)\n }\n return String(param)\n}\n\nconst extractError = (params: unknown[]): Error => {\n const found = params.find((p): p is Error => p instanceof Error)\n if (found) {\n return found\n }\n return new Error(params.map(formatParam).join(' '))\n}\n\nconst formatParams = (params: unknown[]): string => {\n return params.map(formatParam).join(' ')\n}\n\nconst isServerSide = typeof window === 'undefined'\n// `import.meta.env` only exists in Vite builds: the cast keeps this file\n// compilable under plain Node tsconfigs (e.g. apps/azure-functions)\nconst isLocal = isServerSide\n ? process?.env?.VITE_LOCAL === 'true'\n : (import.meta as { env?: Record<string, unknown> }).env?.VITE_LOCAL ===\n 'true'\n\nconst isLoggingEnabled = isLocal || isServerSide\n\n/**\n * Console severity floor, read from `LOG_LEVEL`.\n *\n * The OTel bridge below has always honoured that variable, which is why\n * production exports no INFO rows. The console writers did not, and\n * `isLoggingEnabled` is unconditionally true on a server, so every info line\n * still reached stdout in every environment: the two sinks disagreed, and the\n * container log pipeline kept billing for rows nobody could query. Measured on\n * 2026-09-02: one knowledge-base search wrote three of them, one carrying 500\n * characters of dense-vector JSON, three times per turn.\n *\n * The default is `info`, so an environment that sets nothing keeps exactly the\n * output it has today. Note that an `error` is still tracked and exported when\n * the floor hides it from the console: only the console write is gated.\n */\nconst LEVEL_WEIGHT: Record<string, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n fatal: 50,\n}\nconst readLevel = (level: string | undefined): number =>\n LEVEL_WEIGHT[(level ?? '').toLowerCase()] ?? LEVEL_WEIGHT.info\n\nlet _consoleFloor = isServerSide\n ? readLevel(process?.env?.LOG_LEVEL)\n : LEVEL_WEIGHT.info\n\n/**\n * Overrides the console floor for a level chosen at runtime rather than by\n * env, mirroring `setLogLevel` on the OTel side. The backend calls both from\n * one place so the two sinks cannot drift (`apps/backend/src/main.ts`).\n */\nexport const setConsoleLogLevel = (level: string): void => {\n _consoleFloor = readLevel(level)\n}\n\n/** Whether a message of this severity should reach the console. */\nconst printsAt = (level: 'debug' | 'info' | 'warn' | 'error'): boolean =>\n isLoggingEnabled && LEVEL_WEIGHT[level] >= _consoleFloor\n\nexport const log = (...params: unknown[]) => {\n if (printsAt('info')) {\n // eslint-disable-next-line no-console\n console.log(...params)\n }\n _otelBridge?.logInfo(formatParams(params))\n}\n\nexport const error = (...params: unknown[]) => {\n const err = extractError(params)\n _exceptionTracker?.(err)\n _otelBridge?.logException(err)\n if (printsAt('error')) {\n // eslint-disable-next-line no-console\n console.error(formatParams(params))\n }\n}\n\nexport const info = (...params: unknown[]) => {\n if (printsAt('info')) {\n // eslint-disable-next-line no-console\n console.info(...params)\n }\n _otelBridge?.logInfo(formatParams(params))\n}\n\nexport const debug = (...params: unknown[]) => {\n if (printsAt('debug')) {\n // eslint-disable-next-line no-console\n console.debug(...params)\n }\n _otelBridge?.logDebug(formatParams(params))\n}\n\nexport const warn = (...params: unknown[]) => {\n // A warning is not an exception: it must never reach `app_errors`, so\n // the OTel bridge gets only logWarn. The exception tracker stays: it is\n // wired in the frontend only (Application Insights trackException).\n const err = extractError(params)\n _exceptionTracker?.(err)\n // Serialize once for both sinks: the walk is depth-capped but not free.\n const text = formatParams(params)\n _otelBridge?.logWarn(text)\n if (printsAt('warn')) {\n // eslint-disable-next-line no-console\n console.warn(text)\n }\n}\n\n/**\n * The console rendering of a fixed message plus attributes: ONE line, with the\n * attributes as JSON after the message. `console.warn(message, attrs)` lets\n * Node's inspector break a wide object across several lines, and a container\n * log pipeline stores each line as its own row, so the query that reads the\n * attributes back finds the first row and a fragment. `formatParams` also\n * redacts the sensitive keys and survives a circular reference.\n */\nconst withAttrs = (message: string, attrs?: Record<string, unknown>): string =>\n attrs ? formatParams([message, attrs]) : message\n\n/**\n * WARN with a fixed message and structured attributes. Prefer this over\n * interpolating values into the message: a fixed message keeps the log\n * stream groupable (and therefore alertable), the values stay queryable\n * as attributes.\n */\nexport const warnAttrs = (message: string, attrs?: Record<string, unknown>) => {\n _otelBridge?.logWarn(message, attrs)\n if (printsAt('warn')) {\n // eslint-disable-next-line no-console\n console.warn(withAttrs(message, attrs))\n }\n}\n\n/**\n * A measurement event: one fixed name, the ids as attributes, and **neither\n * sink drops it**, whatever `LOG_LEVEL` says.\n *\n * The info twin of {@link warnAttrs} used to be an ordinary INFO line, and that\n * was wrong in the one environment it exists for: production runs at\n * `LOG_LEVEL=warn`, so the console floor and the OTel floor would each have\n * dropped it and the measurement it feeds would have read zero rows and been\n * believed. WARN is not the answer either, because these events fire on the\n * majority of turns and a normal event at WARN degrades the level alerting\n * watches. So this is a channel, not a level: severity stays INFO and the floor\n * does not apply.\n *\n * The price is that nothing else may use it. Keep the callers few\n * (`closure_gate.refused`, `closure_recovery.applied`) and the volume of the\n * order of one row per turn, and never pass a message with the values\n * interpolated into it: a fixed name is what makes the rows groupable by agent\n * instead of countable by regex.\n */\nexport const logEvent = (name: string, attrs?: Record<string, unknown>) => {\n _otelBridge?.logEvent(name, attrs)\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.log(withAttrs(name, attrs))\n }\n}\n\nexport const assert = (condition: boolean | undefined, message: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.assert(condition, message)\n }\n}\n\nexport const clear = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.clear()\n }\n}\n\n/**\n * A table is an info line that happens to be wide, so it answers to the floor\n * like one. It used to check only `isLoggingEnabled`, which left the usage\n * table of every turn on the console of an environment set to `warn`, and made\n * it the last write of a turn in the test run: vitest reports a console write\n * that outlives its test as `Closing rpc while \"onUserConsoleLog\" was pending`\n * and fails a run whose tests all passed.\n */\nexport const table = (table: unknown) => {\n if (printsAt('info')) {\n // eslint-disable-next-line no-console\n console.table(table)\n }\n}\n\nexport const group = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.group(name)\n }\n}\n\nexport const groupEnd = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n}\n\nexport const time = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.time(name)\n }\n}\n\nexport const timeEnd = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(name)\n }\n}\n\nexport const timeLog = (name: string, ...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeLog(name, ...params)\n }\n}\n\nexport const logger = {\n log,\n error,\n info,\n debug,\n warn,\n warnAttrs,\n logEvent,\n assert,\n clear,\n table,\n group,\n groupEnd,\n time,\n timeEnd,\n timeLog,\n}\n\nexport const useErrorsLogger = (errors: Ref<Error | null | undefined>[]) => {\n // Vue is an optional runtime dependency for the backend build.\n // Lazily import it only when running in a browser/Vue environment.\n if (typeof window === 'undefined') {\n return\n }\n\n void import('vue').then(({ watch }) => {\n errors.forEach((error) => {\n watch(error, (value) => {\n logger.error(value)\n })\n })\n })\n}\n","/**\n * Signature of the calls the function app makes to the backend's internal\n * routes (spec agent-wakeup, \"Timer: coda, function, endpoint interno\"). Both\n * ends share `INTERNAL_API_SECRET`; the signed payload binds the method, the\n * path, the body and a timestamp, so a captured request cannot be replayed on\n * another route nor after the tolerance window.\n *\n * WebCrypto, not `node:crypto`: this package is imported by the browser too.\n */\nexport const INTERNAL_SIGNATURE_HEADER = 'x-internal-signature'\nexport const INTERNAL_TIMESTAMP_HEADER = 'x-internal-timestamp'\nexport const INTERNAL_SIGNATURE_TOLERANCE_MS = 5 * 60_000\n\ninterface InternalRequest {\n secret: string\n method: string\n /** The path as the server routes it, without host or querystring. */\n path: string\n body: string\n}\n\nconst encoder = new TextEncoder()\n\nconst hmacSha256Hex = async (secret: string, payload: string) => {\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const signature = await globalThis.crypto.subtle.sign(\n 'HMAC',\n key,\n encoder.encode(payload),\n )\n return Array.from(new Uint8Array(signature), (byte) =>\n byte.toString(16).padStart(2, '0'),\n ).join('')\n}\n\nconst signedPayload = (\n { method, path, body }: InternalRequest,\n timestamp: string,\n) => `${timestamp}.${method.toUpperCase()}.${path}.${body}`\n\n/** Constant-time comparison of two hex strings. */\nconst sameHex = (a: string, b: string) => {\n if (a.length !== b.length) {\n return false\n }\n let difference = 0\n for (let index = 0; index < a.length; index++) {\n difference |= a.charCodeAt(index) ^ b.charCodeAt(index)\n }\n return difference === 0\n}\n\n/** The two headers that sign an internal request. */\nexport async function signInternalRequest(\n request: InternalRequest,\n now = Date.now(),\n): Promise<Record<string, string>> {\n const timestamp = String(now)\n return {\n [INTERNAL_TIMESTAMP_HEADER]: timestamp,\n [INTERNAL_SIGNATURE_HEADER]: await hmacSha256Hex(\n request.secret,\n signedPayload(request, timestamp),\n ),\n }\n}\n\n/**\n * Whether the headers sign this request with this secret, within the\n * tolerance window.\n */\nexport async function verifyInternalRequest(\n request: InternalRequest & {\n signature: string | undefined\n timestamp: string | undefined\n },\n now = Date.now(),\n): Promise<boolean> {\n const { signature, timestamp } = request\n if (!signature || !timestamp || !/^\\d+$/.test(timestamp)) {\n return false\n }\n if (Math.abs(now - Number(timestamp)) > INTERNAL_SIGNATURE_TOLERANCE_MS) {\n return false\n }\n const expected = await hmacSha256Hex(\n request.secret,\n signedPayload(request, timestamp),\n )\n return sameHex(expected, signature.toLowerCase())\n}\n","// E.164 country codes are prefix-free: one digit for these two, two digits\n// for the next set, three for every other one. Reading \"the first one to four\n// digits\" took four, so +44 1234 567890 came out as +4412.\nconst ONE_DIGIT_COUNTRY_CODES = new Set(['1', '7'])\nconst TWO_DIGIT_COUNTRY_CODES = new Set(\n (\n '20 27 30 31 32 33 34 36 39 40 41 43 44 45 46 47 48 49 51 52 53 54 55 ' +\n '56 57 58 60 61 62 63 64 65 66 81 82 84 86 90 91 92 93 94 95 98'\n ).split(' '),\n)\n\n/** Splits international digits into country code and national number. */\nfunction splitCountryCode(digits: string): [string, string] | undefined {\n const length = ONE_DIGIT_COUNTRY_CODES.has(digits.slice(0, 1))\n ? 1\n : TWO_DIGIT_COUNTRY_CODES.has(digits.slice(0, 2))\n ? 2\n : 3\n return digits.length > length\n ? [digits.slice(0, length), digits.slice(length)]\n : undefined\n}\n\n/**\n * Formats a phone number with international prefix, its groups separated by\n * spaces as a person writes them\n * If no international prefix is provided, defaults to Italian (+39)\n *\n * @param phone - The phone number to format\n * @param defaultPrefix - The default international prefix (default: '+39')\n * @returns Formatted phone number (e.g., '+39 392 4096227')\n *\n * @example\n * formatPhoneNumber('3924096227') // '+39 392 4096227'\n * formatPhoneNumber('+393924096227') // '+39 392 4096227'\n * formatPhoneNumber('00393924096227') // '+39 392 4096227'\n * formatPhoneNumber('393924096227') // '+39 392 4096227'\n * formatPhoneNumber('0450000101') // '+39 045 0000101'\n */\nexport function formatPhoneNumber(\n phone: string | null | undefined,\n defaultPrefix = '+39',\n): string {\n if (!phone) {\n return ''\n }\n\n // Remove all non-digit characters except + at the beginning\n const cleaned = phone.trim().replace(/[^\\d+]/g, '')\n\n if (!cleaned) {\n return ''\n }\n\n // Normalize the phone number to have international prefix\n let nationalNumber = ''\n let countryCode = defaultPrefix.replace('+', '')\n\n // Handle different input formats\n if (cleaned.startsWith('+')) {\n // Already has + prefix: +393924096227\n const match = cleaned.match(/^\\+(\\d+)$/)\n if (match) {\n const digits = match[1]\n // Extract country code and national number\n if (digits.startsWith(countryCode)) {\n nationalNumber = digits.substring(countryCode.length)\n } else {\n const split = splitCountryCode(digits)\n if (split) {\n ;[countryCode, nationalNumber] = split\n }\n }\n }\n } else if (cleaned.startsWith('00')) {\n // International format without +: 00393924096227\n const digits = cleaned.substring(2)\n if (digits.startsWith(countryCode)) {\n nationalNumber = digits.substring(countryCode.length)\n } else {\n const split = splitCountryCode(digits)\n if (split) {\n ;[countryCode, nationalNumber] = split\n }\n }\n } else if (\n cleaned.startsWith(countryCode) &&\n cleaned.length > countryCode.length + 8\n ) {\n // Starts with country code but no +: 393924096227\n nationalNumber = cleaned.substring(countryCode.length)\n } else {\n // Local number: 3924096227 or 0450000101\n nationalNumber = cleaned\n // The national trunk 0 is not dialled after the country code, except\n // in Italy, where it belongs to the landline number (045 is Verona):\n // dropping it turned 045 0000101 into another number\n if (\n countryCode !== '39' &&\n nationalNumber.startsWith('0') &&\n nationalNumber.length > 1\n ) {\n nationalNumber = nationalNumber.substring(1)\n }\n }\n\n if (!nationalNumber) {\n return phone\n }\n\n const prefix = `+${countryCode}`\n\n // Italian mobile numbers: 3XX XXXXXXX (10 digits total, starting with 3)\n if (\n countryCode === '39' &&\n nationalNumber.length === 10 &&\n nationalNumber.startsWith('3')\n ) {\n return `${prefix} ${nationalNumber.substring(0, 3)} ${nationalNumber.substring(3)}`\n }\n\n // Italian landline numbers: 0XX XXXXXXX (9-11 digits, starting with 0)\n if (\n countryCode === '39' &&\n nationalNumber.length >= 9 &&\n nationalNumber.length <= 11 &&\n nationalNumber.startsWith('0')\n ) {\n const areaCode = nationalNumber.substring(0, 3)\n const rest = nationalNumber.substring(3)\n return `${prefix} ${areaCode} ${rest}`\n }\n\n // Generic formatting: group by 3-4 digits\n const parts: string[] = []\n let remaining = nationalNumber\n\n while (remaining.length > 0) {\n if (remaining.length <= 4) {\n parts.push(remaining)\n break\n }\n parts.push(remaining.substring(0, 3))\n remaining = remaining.substring(3)\n }\n\n return `${prefix} ${parts.join(' ')}`\n}\n\n/**\n * Returns a formatted phone number or a dash if empty\n * Useful for displaying in tables\n *\n * @param phone - The phone number to format\n * @param defaultPrefix - The default international prefix (default: '+39')\n * @returns Formatted phone number or '-'\n */\nexport function formatPhoneNumberOrDash(\n phone: string | null | undefined,\n defaultPrefix = '+39',\n): string {\n const formatted = formatPhoneNumber(phone, defaultPrefix)\n return formatted || '-'\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { C as e, D as t, O as n, S as r, _ as i, a, g as o, h as s, i as c, l, m as u, o as d, p as f, r as p, s as m, u as h, v as g, w as _, x as v } from "./schemas-Bu1lick6.js";
2
2
  import { N as y } from "./Agent-DU1WWaHR.js";
3
- import { r as b, t as ee } from "./createChatbotApiClient-BdmGCAQR.js";
4
- import { t as te } from "./src-DCfvejyT.js";
3
+ import { r as b, t as ee } from "./createChatbotApiClient-G3Tt1I67.js";
4
+ import { t as te } from "./src-DpkuiHam.js";
5
5
  import { r as ne, u as re } from "./message-BOiF6Bt5.js";
6
- import { t as ie } from "./useSafeLocalStorage-OwzVTZud.js";
6
+ import { t as ie } from "./useSafeLocalStorage-DLIc8pkn.js";
7
7
  import { computed as x, getCurrentScope as ae, isReadonly as oe, onScopeDispose as se, reactive as ce, ref as S, toRefs as le, watch as ue, watchEffect as de } from "vue";
8
8
  import { useI18n as fe } from "vue-i18n";
9
9
  import { usePreferredDark as pe } from "@vueuse/core";
@@ -3938,4 +3938,4 @@ function Nr(e) {
3938
3938
  //#endregion
3939
3939
  export { V as a, Qn as i, Nr as n, Tr as r, Er as t };
3940
3940
 
3941
- //# sourceMappingURL=useChatbotStore-BAv5K91p.js.map
3941
+ //# sourceMappingURL=useChatbotStore-C1sgxgD1.js.map