@aigentyc/chat-sdk 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChatInterface-2MN5cpYB.d.ts → ChatInterface-CRmM_RG_.d.ts} +9 -1
- package/dist/{ChatInterface-BnVyOUG5.d.cts → ChatInterface-DKF3BY42.d.cts} +9 -1
- package/dist/{SlotsContext-BZBi51ZT.d.ts → SlotsContext-B_087V7B.d.ts} +11 -2
- package/dist/{SlotsContext-D_C7zlUA.d.cts → SlotsContext-DAQiASVu.d.cts} +11 -2
- package/dist/ai-elements.cjs +39 -27
- package/dist/ai-elements.d.cts +63 -1
- package/dist/ai-elements.d.ts +63 -1
- package/dist/ai-elements.js +2 -2
- package/dist/{chunk-3MP2EGEJ.cjs → chunk-72QJ2ORD.cjs} +4 -2
- package/dist/chunk-72QJ2ORD.cjs.map +1 -0
- package/dist/{chunk-KTYYLZN7.cjs → chunk-B277MAUK.cjs} +76 -4
- package/dist/chunk-B277MAUK.cjs.map +1 -0
- package/dist/{chunk-P3RPAI4F.cjs → chunk-BYX6IOGX.cjs} +4 -4
- package/dist/{chunk-P3RPAI4F.cjs.map → chunk-BYX6IOGX.cjs.map} +1 -1
- package/dist/chunk-CNPYBLLT.js +81 -0
- package/dist/chunk-CNPYBLLT.js.map +1 -0
- package/dist/{chunk-FJZL33KP.js → chunk-CW6LCVNC.js} +3 -3
- package/dist/{chunk-FJZL33KP.js.map → chunk-CW6LCVNC.js.map} +1 -1
- package/dist/{chunk-D75TDRBH.js → chunk-JAEXKKSE.js} +41 -35
- package/dist/chunk-JAEXKKSE.js.map +1 -0
- package/dist/{chunk-Q3UJEIBN.cjs → chunk-JEK2V5I3.cjs} +6 -6
- package/dist/{chunk-Q3UJEIBN.cjs.map → chunk-JEK2V5I3.cjs.map} +1 -1
- package/dist/{chunk-7ESWDFF5.cjs → chunk-KHQYSEYN.cjs} +244 -146
- package/dist/chunk-KHQYSEYN.cjs.map +1 -0
- package/dist/{chunk-QYCEHFAB.js → chunk-LDQVDUUJ.js} +4 -2
- package/dist/chunk-LDQVDUUJ.js.map +1 -0
- package/dist/{chunk-5XF3NEFB.js → chunk-O5TPHZRP.js} +74 -5
- package/dist/chunk-O5TPHZRP.js.map +1 -0
- package/dist/{chunk-BWWN5LSE.js → chunk-PNUHUUA3.js} +221 -124
- package/dist/chunk-PNUHUUA3.js.map +1 -0
- package/dist/{chunk-52ZHMTAA.cjs → chunk-UXVOUC2A.cjs} +41 -35
- package/dist/chunk-UXVOUC2A.cjs.map +1 -0
- package/dist/{chunk-IU7Q7O5G.js → chunk-VQPOUMBC.js} +3 -3
- package/dist/{chunk-IU7Q7O5G.js.map → chunk-VQPOUMBC.js.map} +1 -1
- package/dist/chunk-VYBHYFG3.cjs +87 -0
- package/dist/chunk-VYBHYFG3.cjs.map +1 -0
- package/dist/components.cjs +20 -19
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +2 -2
- package/dist/components.d.ts +2 -2
- package/dist/components.js +8 -7
- package/dist/components.js.map +1 -1
- package/dist/core.cjs +21 -82
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -78
- package/dist/core.js.map +1 -1
- package/dist/hooks.cjs +9 -8
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +2 -2
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +4 -3
- package/dist/hooks.js.map +1 -1
- package/dist/i18n.cjs +5 -5
- package/dist/i18n.d.cts +2 -2
- package/dist/i18n.d.ts +2 -2
- package/dist/i18n.js +1 -1
- package/dist/index.cjs +35 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +18 -13
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +10 -10
- package/dist/styles.css +1 -1
- package/dist/theme.cjs +4 -4
- package/dist/theme.d.cts +1 -1
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +2 -2
- package/dist/tools.cjs +6 -5
- package/dist/tools.d.cts +2 -2
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +3 -2
- package/dist/{types-bsR_-fq8.d.cts → types-DRa1zFlN.d.cts} +10 -1
- package/dist/{types-bsR_-fq8.d.ts → types-DRa1zFlN.d.ts} +10 -1
- package/package.json +2 -2
- package/dist/chunk-3MP2EGEJ.cjs.map +0 -1
- package/dist/chunk-52ZHMTAA.cjs.map +0 -1
- package/dist/chunk-5XF3NEFB.js.map +0 -1
- package/dist/chunk-7ESWDFF5.cjs.map +0 -1
- package/dist/chunk-BWWN5LSE.js.map +0 -1
- package/dist/chunk-D75TDRBH.js.map +0 -1
- package/dist/chunk-KTYYLZN7.cjs.map +0 -1
- package/dist/chunk-QYCEHFAB.js.map +0 -1
package/dist/components.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ChatInputWithAttachments.tsx","../src/ui/sheet.tsx","../src/components/ChatDrawer.tsx","../src/components/VisitorIdentityForm.tsx","../src/components/LiveChatHeader.tsx","../src/components/LiveChatQueueBanner.tsx","../src/components/SatisfactionRating.tsx"],"names":["jsx","jsxs","X","useState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBO,SAAS,wBAAA,CAAyB;AAAA,EACxC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,GAAe,KAAA;AAAA,EACf,WAAA,GAAc;AACf,CAAA,EAAkC;AACjC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,CAAuB,EAAE,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,OAAyB,IAAI,CAAA;AAElD,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA6C;AACnE,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,KAAY,KAAA,CAAM,IAAA,MAAU,WAAA,CAAY,MAAA,GAAS,CAAA,CAAA,IAAM,CAAC,YAAA,EAAc;AACnF,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,YAAA,EAAa;AAAA,IACd;AAAA,EACD,CAAA;AAEA,EAAA,MAAM,eAAe,MAAM;AAC1B,IAAA,IAAK,CAAC,KAAA,CAAM,IAAA,MAAU,WAAA,CAAY,MAAA,KAAW,KAAM,YAAA,EAAc;AACjE,IAAA,MAAM,SAAA,GAA0B,WAAA,CAAY,GAAA,CAAI,CAAC,EAAE,IAAI,GAAA,EAAK,GAAG,IAAA,EAAK,KAAM,IAAI,CAAA;AAC9E,IAAA,QAAA,CAAS,KAAA,EAAO,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,YAAY,MAAS,CAAA;AAC5D,IAAA,cAAA,CAAe,EAAE,CAAA;AAAA,EAClB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,CAAA,KAA2C;AAC1E,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,CAAO,KAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,MAAM,iBAA+B,EAAC;AAEtC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,EAAG;AACrC,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,EAAG;AACrC,MAAA,MAAM,OAAA,GAAU,MAAM,aAAA,CAAc,IAAI,CAAA;AACxC,MAAA,cAAA,CAAe,IAAA,CAAK;AAAA,QACnB,EAAA,EAAI,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAAA,QACxD,IAAA,EAAM,MAAA;AAAA,QACN,GAAA,EAAK,OAAA;AAAA,QACL,WAAW,IAAA,CAAK,IAAA;AAAA,QAChB,UAAU,IAAA,CAAK;AAAA,OACf,CAAA;AAAA,IACF;AAEA,IAAA,cAAA,CAAe,CAAC,IAAA,KAAS,CAAC,GAAG,IAAA,EAAM,GAAG,cAAc,CAAC,CAAA;AACrD,IAAA,CAAA,CAAE,OAAO,KAAA,GAAQ,EAAA;AAAA,EAClB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,EAAA,KAAe;AACxC,IAAA,cAAA,CAAe,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AAAA,EACzD,CAAA;AAEA,EAAA,MAAM,iBAAiB,MAAM;AAC5B,IAAA,YAAA,CAAa,SAAS,KAAA,EAAM;AAAA,EAC7B,CAAA;AAEA,EAAA,uBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,IAAA,WAAA,CAAY,MAAA,GAAS,qBACrB,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2BAAA,EACb,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,UAAA,qBACjB,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEA,SAAA,EAAU,+DAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACA,KAAK,UAAA,CAAW,GAAA;AAAA,cAChB,GAAA,EAAK,WAAW,QAAA,IAAY,YAAA;AAAA,cAC5B,SAAA,EAAU;AAAA;AAAA,WACX;AAAA,0BACA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,MAAM,gBAAA,CAAiB,UAAA,CAAW,EAAE,CAAA;AAAA,cAC7C,SAAA,EAAU,0JAAA;AAAA,cAEV,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AACxB;AAAA,OAAA;AAAA,MAdK,UAAA,CAAW;AAAA,KAgBjB,CAAA,EACF,CAAA;AAAA,oBAGD,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,SAAA,EAAU,wGAAA;AAAA,QACV,KAAA,EAAO,EAAE,eAAA,EAAiB,sBAAA,EAAwB,aAAa,kBAAA,EAAmB;AAAA,QAElF,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,cAAA;AAAA,cACT,QAAA,EAAU,YAAA;AAAA,cACV,SAAA,EAAU,4JAAA;AAAA,cACV,KAAA,EAAM,cAAA;AAAA,cAEN,QAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,WAChC;AAAA,0BAEA,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACA,GAAA,EAAK,YAAA;AAAA,cACL,IAAA,EAAK,MAAA;AAAA,cACL,MAAA,EAAO,SAAA;AAAA,cACP,QAAA,EAAQ,IAAA;AAAA,cACR,QAAA,EAAU,gBAAA;AAAA,cACV,SAAA,EAAU;AAAA;AAAA,WACX;AAAA,0BAEA,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,MAAA;AAAA,cACL,KAAA;AAAA,cACA,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cACxC,SAAA,EAAW,aAAA;AAAA,cACX,QAAA,EAAU,YAAA;AAAA,cACV,WAAA;AAAA,cACA,SAAA,EAAU,+FAAA;AAAA,cACV,KAAA,EAAO,EAAE,KAAA,EAAO,gBAAA;AAAiB;AAAA,WAClC;AAAA,0BAEA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,YAAA;AAAA,cACT,UAAW,CAAC,KAAA,CAAM,MAAK,IAAK,WAAA,CAAY,WAAW,CAAA,IAAM,YAAA;AAAA,cACzD,SAAA,EAAU,4JAAA;AAAA,cACV,KAAA,EAAO,EAAE,eAAA,EAAiB,mBAAA,EAAqB,OAAO,oCAAA,EAAqC;AAAA,cAE1F,QAAA,EAAA,YAAA,uBACC,MAAA,EAAA,EAAO,SAAA,EAAU,sBAAqB,CAAA,mBAEvC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EAAwB,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,OAAM,4BAAA,EAC5E,QAAA,kBAAA,GAAA,CAAC,UAAK,CAAA,EAAE,+ZAAA,EAAga,IAAA,EAAK,OAAA,EAAQ,CAAA,EACtb;AAAA;AAAA;AAEF;AAAA;AAAA;AACD,GAAA,EACD,CAAA;AAEF;AAEA,eAAe,cAAc,IAAA,EAA6B;AACzD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACvC,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAC9B,IAAA,MAAA,CAAO,MAAA,GAAS,MAAM,OAAA,CAAQ,MAAA,CAAO,MAAgB,CAAA;AACrD,IAAA,MAAA,CAAO,OAAA,GAAU,MAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,EAC1B,CAAC,CAAA;AACF;AC3JA,IAAM,KAAA,GAAuB,cAAA,CAAA,IAAA;AAE7B,IAAM,YAAA,GAA8B,cAAA,CAAA,OAAA;AAIpC,IAAM,WAAA,GAA6B,cAAA,CAAA,MAAA;AAEnC,IAAM,YAAA,GAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAgB,cAAA,CAAA,OAAA;AAAA,EAAf;AAAA,IACC,SAAA,EAAW,EAAA;AAAA,MACT,yJAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG,KAAA;AAAA,IACJ;AAAA;AACF,CACD,CAAA;AACD,YAAA,CAAa,cAA6B,cAAA,CAAA,OAAA,CAAQ,WAAA;AAElD,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,kMAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM;AAAA,QACJ,GAAA,EAAK,mGAAA;AAAA,QACL,MAAA,EACE,4GAAA;AAAA,QACF,IAAA,EAAM,+HAAA;AAAA,QACN,KAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AAQA,IAAM,eAAqB,KAAA,CAAA,UAAA,CAGzB,CAAC,EAAE,IAAA,GAAO,SAAS,SAAA,EAAW,QAAA,EAAU,cAAA,EAAgB,eAAA,EAAiB,GAAG,KAAA,EAAM,EAAG,GAAA,qBACrFC,KAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,kBAAAD,IAAC,YAAA,EAAA,EAAa,CAAA;AAAA,kBACdC,IAAAA;AAAA,IAAgB,cAAA,CAAA,OAAA;AAAA,IAAf;AAAA,MACC,GAAA;AAAA,MACA,WAAW,EAAA,CAAG,aAAA,CAAc,EAAE,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MAC/C,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAA,IAAAA,CAAgB,cAAA,CAAA,KAAA,EAAf,EAAqB,SAAA,EAAU,0OAAA,EAC9B,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAACE,CAAAA,EAAA,EAAE,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,0BACvBF,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,OAAA,EAAK;AAAA,SAAA,EACjC,CAAA;AAAA,QACC;AAAA;AAAA;AAAA;AACH,CAAA,EACF,CACD,CAAA;AACD,YAAA,CAAa,cAA6B,cAAA,CAAA,OAAA,CAAQ,WAAA;AA8BlD,IAAM,UAAA,GAAmB,iBAGvB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAgB,cAAA,CAAA,KAAA;AAAA,EAAf;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,IAC/D,GAAG;AAAA;AACN,CACD,CAAA;AACD,UAAA,CAAW,cAA6B,cAAA,CAAA,KAAA,CAAM,WAAA;AAE9C,IAAM,gBAAA,GAAyB,iBAG7B,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAgB,cAAA,CAAA,WAAA;AAAA,EAAf;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,IACvD,GAAG;AAAA;AACN,CACD,CAAA;AACD,gBAAA,CAAiB,cAA6B,cAAA,CAAA,WAAA,CAAY,WAAA;AC/GnD,SAAS,UAAA,CAAW;AAAA,EAC1B,WAAA,GAAc,KAAA;AAAA,EACd,IAAA,EAAM,cAAA;AAAA,EACN,YAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA,GAAc;AACf,CAAA,EAAoB;AACnB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIG,SAAS,WAAW,CAAA;AAE5D,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,GAAiB,YAAA;AAE/C,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAAkB;AAC3C,IAAA,IAAI,CAAC,YAAA,EAAc,eAAA,CAAgB,IAAI,CAAA;AACvC,IAAA,YAAA,GAAe,IAAI,CAAA;AAAA,EACpB,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACf,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,IAAA,MAAM,eAAA,GAAkB,MAAM,gBAAA,CAAiB,KAAK,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,uBAAuB,eAAe,CAAA;AAChE,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,qBAAA,EAAuB,eAAe,CAAA;AAAA,EAEjF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,uBACCF,IAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,cAAc,gBAAA,EACjC,QAAA,EAAA;AAAA,IAAA,CAAC,+BACDD,GAAAA,CAAC,gBAAa,OAAA,EAAO,IAAA,EACnB,qCACAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,wLAAA;AAAA,QACV,KAAA,EAAO,EAAE,eAAA,EAAiB,mBAAA,EAAqB,OAAO,oCAAA,EAAqC;AAAA,QAC3F,YAAA,EAAW,WAAA;AAAA,QAEX,QAAA,kBAAAA,GAAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,KACpC,EAEF,CAAA;AAAA,oBAEDC,IAAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,EAAU,0EAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAD,IAAgB,cAAA,CAAA,IAAA,EAAf,EACA,0BAAAA,GAAAA,CAAC,UAAA,EAAA,EAAW,4BAAc,CAAA,EAC3B,CAAA;AAAA,0BACAA,IAAC,aAAA,EAAA,EAAc;AAAA;AAAA;AAAA;AAChB,GAAA,EACD,CAAA;AAEF;AC3DO,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAU,QAAA,EAAS,EAA6B;AACrF,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIG,SAAS,EAAE,CAAA;AACnC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAS,EAAE,CAAA;AACrC,EAAA,MAAM,EAAE,CAAA,EAAG,SAAA,EAAU,GAAI,OAAA,EAAQ;AACjC,EAAA,MAAM,QAAQ,SAAA,KAAc,KAAA;AAE5B,EAAA,uBACCF,KAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAmC,GAAA,EAAK,KAAA,GAAQ,QAAQ,KAAA,EACtE,QAAA,EAAA;AAAA,oBAAAD,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAA,EAA0C,QAAA,EAAA,CAAA,CAAE,uBAAuB,CAAA,EAAE,CAAA;AAAA,oBAClFC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,MAAA;AAAA,UACL,KAAA,EAAO,IAAA;AAAA,UACP,UAAU,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,UACvC,WAAA,EAAa,EAAE,sBAAsB,CAAA;AAAA,UACrC,SAAA,EAAU,0GAAA;AAAA,UACV,SAAA,EAAS;AAAA;AAAA,OACV;AAAA,sBACAA,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,OAAA;AAAA,UACL,KAAA,EAAO,KAAA;AAAA,UACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,UACxC,WAAA,EAAa,EAAE,uBAAuB,CAAA;AAAA,UACtC,SAAA,EAAU;AAAA;AAAA,OACX;AAAA,sBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACd,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,QAAA;AAAA,YACT,SAAA,EAAU,0EAAA;AAAA,YAET,YAAE,gBAAgB;AAAA;AAAA,SACpB;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AAAA,YACnC,UAAU,CAAC,IAAA,CAAK,MAAK,IAAK,CAAC,MAAM,IAAA,EAAK;AAAA,YACtC,SAAA,EAAU,6DAAA;AAAA,YACV,KAAA,EAAO,EAAE,eAAA,EAAiB,4BAAA,EAA6B;AAAA,YAEtD,YAAE,yBAAyB;AAAA;AAAA;AAC7B,OAAA,EACD;AAAA,KAAA,EACD;AAAA,GAAA,EACD,CAAA;AAEF;ACjDO,SAAS,cAAA,CAAe,EAAE,YAAA,EAAc,SAAA,EAAU,EAAwB;AAChF,EAAA,uBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mFAAA,EACd,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAA,EAAoC,CAAA;AAAA,sBACnDC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oCAAA,EAAqC,QAAA,EAAA;AAAA,QAAA,gBAAA;AAAA,QAAe;AAAA,OAAA,EAAa;AAAA,KAAA,EAClF,CAAA;AAAA,oBACAD,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,SAAA;AAAA,QACT,SAAA,EAAU,qEAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EACD,CAAA;AAEF;AChBO,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAU,QAAA,EAAS,EAAqB;AAC7E,EAAA,uBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iFAAA,EACd,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EAAiD,CAAA;AAAA,sBAChEC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA;AAAA,QAAA,oCAAA;AAAA,QAEtC,WAAW,CAAA,oBAAKA,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,aAAA,EAAc,QAAA,EAAA;AAAA,UAAA,aAAA;AAAA,UAAY;AAAA,SAAA,EAAS;AAAA,OAAA,EACrE;AAAA,KAAA,EACD,CAAA;AAAA,oBACAD,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,QAAA;AAAA,QACT,SAAA,EAAU,qDAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EACD,CAAA;AAEF;AChBO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAU,MAAA,EAAO,EAA4B;AACjF,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIG,SAAyC,IAAI,CAAA;AAC7E,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,EAAE,CAAA;AACzC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAS,KAAK,CAAA;AAEhD,EAAA,IAAI,SAAA,EAAW;AACd,IAAA,uBACCF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+BAAA,EAAgC,QAAA,EAAA,8BAAA,EAA4B,CAAA;AAAA,sBACzEA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,MAAA;AAAA,UACT,SAAA,EAAU,4CAAA;AAAA,UACV,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACD,CAAA;AAAA,EAEF;AAEA,EAAA,uBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACd,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6CAAA,EAA8C,QAAA,EAAA,0BAAA,EAAwB,CAAA;AAAA,oBACnFC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,MAAM,WAAA,CAAY,UAAU,CAAA;AAAA,UACrC,SAAA,EAAW,CAAA,mCAAA,EACV,QAAA,KAAa,UAAA,GAAa,gCAAgC,sCAC3D,CAAA,CAAA;AAAA,UAEA,QAAA,kBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,OAC/B;AAAA,sBACAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,MAAM,WAAA,CAAY,UAAU,CAAA;AAAA,UACrC,SAAA,EAAW,CAAA,mCAAA,EACV,QAAA,KAAa,UAAA,GAAa,4BAA4B,sCACvD,CAAA,CAAA;AAAA,UAEA,QAAA,kBAAAA,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AACjC,KAAA,EACD,CAAA;AAAA,IACC,QAAA,oBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,WAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACA,KAAA,EAAO,OAAA;AAAA,UACP,UAAU,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,UAC1C,WAAA,EAAY,qCAAA;AAAA,UACZ,SAAA,EAAU;AAAA;AAAA,OACX;AAAA,sBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACd,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,SAAS,MAAM;AACd,cAAA,QAAA,CAAS,QAAA,EAAU,WAAW,MAAS,CAAA;AACvC,cAAA,YAAA,CAAa,IAAI,CAAA;AAAA,YAClB,CAAA;AAAA,YACA,SAAA,EAAU,sCAAA;AAAA,YACV,KAAA,EAAO,EAAE,eAAA,EAAiB,mBAAA,EAAoB;AAAA,YAC9C,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAA;AAAA,YACT,SAAA,EAAU,yDAAA;AAAA,YACV,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACD;AAAA,KAAA,EACD,CAAA;AAAA,IAEA,CAAC,QAAA,oBACDA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eACd,QAAA,kBAAAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAU,+CAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA,KAED,EACD;AAAA,GAAA,EAEF,CAAA;AAEF","file":"components.js","sourcesContent":["\"use client\";\n\n/**\n * Chat Input with Image Attachments - Enhanced input for kitchen image analysis\n */\n\nimport { useRef, useState } from \"react\";\nimport { ImageIcon, Square, X } from \"lucide-react\";\n// TODO: `FileUIPart` imported from \"ai\" (Vercel AI SDK). Make sure `ai` is installed as peer dependency.\nimport type { FileUIPart } from \"ai\";\n\ninterface Attachment extends FileUIPart {\n\tid: string;\n}\n\ninterface ChatInputWithAttachmentsProps {\n\tvalue: string;\n\tonChange: (value: string) => void;\n\tonSubmit: (text: string, attachments?: FileUIPart[]) => void;\n\tisProcessing?: boolean;\n\tplaceholder?: string;\n}\n\nexport function ChatInputWithAttachments({\n\tvalue,\n\tonChange,\n\tonSubmit,\n\tisProcessing = false,\n\tplaceholder = \"Ask anything or upload an image...\",\n}: ChatInputWithAttachmentsProps) {\n\tconst [attachments, setAttachments] = useState<Attachment[]>([]);\n\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\n\tconst handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\tif (e.key === \"Enter\" && (value.trim() || attachments.length > 0) && !isProcessing) {\n\t\t\te.preventDefault();\n\t\t\thandleSubmit();\n\t\t}\n\t};\n\n\tconst handleSubmit = () => {\n\t\tif ((!value.trim() && attachments.length === 0) || isProcessing) return;\n\t\tconst fileParts: FileUIPart[] = attachments.map(({ id: _id, ...rest }) => rest);\n\t\tonSubmit(value, fileParts.length > 0 ? fileParts : undefined);\n\t\tsetAttachments([]);\n\t};\n\n\tconst handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\tconst files = e.target.files;\n\t\tif (!files) return;\n\n\t\tconst newAttachments: Attachment[] = [];\n\n\t\tfor (const file of Array.from(files)) {\n\t\t\tif (!file.type.startsWith(\"image/\")) continue;\n\t\t\tconst dataUrl = await fileToDataUrl(file);\n\t\t\tnewAttachments.push({\n\t\t\t\tid: `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n\t\t\t\ttype: \"file\",\n\t\t\t\turl: dataUrl,\n\t\t\t\tmediaType: file.type,\n\t\t\t\tfilename: file.name,\n\t\t\t});\n\t\t}\n\n\t\tsetAttachments((prev) => [...prev, ...newAttachments]);\n\t\te.target.value = \"\";\n\t};\n\n\tconst removeAttachment = (id: string) => {\n\t\tsetAttachments((prev) => prev.filter((a) => a.id !== id));\n\t};\n\n\tconst openFileDialog = () => {\n\t\tfileInputRef.current?.click();\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t{attachments.length > 0 && (\n\t\t\t\t<div className=\"flex flex-wrap gap-2 px-4\">\n\t\t\t\t\t{attachments.map((attachment) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={attachment.id}\n\t\t\t\t\t\t\tclassName=\"relative group rounded-lg overflow-hidden border bg-secondary\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tsrc={attachment.url}\n\t\t\t\t\t\t\t\talt={attachment.filename || \"Attachment\"}\n\t\t\t\t\t\t\t\tclassName=\"h-16 w-16 object-cover\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => removeAttachment(attachment.id)}\n\t\t\t\t\t\t\t\tclassName=\"absolute top-1 right-1 w-5 h-5 rounded-full bg-black/60 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<X className=\"w-3 h-3\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div\n\t\t\t\tclassName=\"flex items-center gap-2 backdrop-blur-xl border shadow-xl rounded-full pl-3 md:pl-4 pr-1.5 md:pr-[6px]\"\n\t\t\t\tstyle={{ backgroundColor: \"var(--ac-background)\", borderColor: \"var(--ac-border)\" }}\n\t\t\t>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={openFileDialog}\n\t\t\t\t\tdisabled={isProcessing}\n\t\t\t\t\tclassName=\"flex items-center justify-center w-9 h-9 rounded-full text-muted-foreground hover:text-foreground hover:bg-secondary transition-colors disabled:opacity-50\"\n\t\t\t\t\ttitle=\"Upload image\"\n\t\t\t\t>\n\t\t\t\t\t<ImageIcon className=\"w-5 h-5\" />\n\t\t\t\t</button>\n\n\t\t\t\t<input\n\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\taccept=\"image/*\"\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={handleFileSelect}\n\t\t\t\t\tclassName=\"hidden\"\n\t\t\t\t/>\n\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tonChange={(e) => onChange(e.target.value)}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\tdisabled={isProcessing}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tclassName=\"flex-1 bg-transparent outline-none text-base min-h-[56px] md:min-h-[69px] disabled:opacity-50\"\n\t\t\t\t\tstyle={{ color: \"var(--ac-text)\" }}\n\t\t\t\t/>\n\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={handleSubmit}\n\t\t\t\t\tdisabled={(!value.trim() && attachments.length === 0) || isProcessing}\n\t\t\t\t\tclassName=\"flex items-center justify-center w-11 h-11 md:w-[55px] md:h-[55px] rounded-full disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0\"\n\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary)\", color: \"var(--ac-primary-foreground, #fff)\" }}\n\t\t\t\t>\n\t\t\t\t\t{isProcessing ? (\n\t\t\t\t\t\t<Square className=\"w-5 h-5 fill-white\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<svg className=\"w-6 h-6 md:w-7 md:h-7\" viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t\t\t<path d=\"M2 15C1.44772 15 1 14.5523 1 14C1 13.4477 1.44772 13 2 13V14L2 15ZM26.7071 13.2929C27.0976 13.6834 27.0976 14.3166 26.7071 14.7071L20.3431 21.0711C19.9526 21.4616 19.3195 21.4616 18.9289 21.0711C18.5384 20.6805 18.5384 20.0474 18.9289 19.6569L24.5858 14L18.9289 8.34315C18.5384 7.95262 18.5384 7.31946 18.9289 6.92893C19.3195 6.53841 19.9526 6.53841 20.3431 6.92893L26.7071 13.2929ZM2 14V13L26 13V14V15L2 15L2 14Z\" fill=\"white\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nasync function fileToDataUrl(file: File): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader();\n\t\treader.onload = () => resolve(reader.result as string);\n\t\treader.onerror = reject;\n\t\treader.readAsDataURL(file);\n\t});\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"../core/utils\"\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst SheetPortal = SheetPrimitive.Portal\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n ref={ref}\n />\n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out\",\n {\n variants: {\n side: {\n top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n bottom:\n \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n right:\n \"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n },\n },\n defaultVariants: {\n side: \"right\",\n },\n }\n)\n\ninterface SheetContentProps\n extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n VariantProps<typeof sheetVariants> {\n overlayVariant?: \"default\" | \"light\";\n}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n SheetContentProps\n>(({ side = \"right\", className, children, overlayVariant: _overlayVariant, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n {children}\n </SheetPrimitive.Content>\n </SheetPortal>\n))\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-start\",\n className\n )}\n {...props}\n />\n)\nSheetHeader.displayName = \"SheetHeader\"\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nSheetFooter.displayName = \"SheetFooter\"\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold text-foreground\", className)}\n {...props}\n />\n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { Sheet, SheetContent, SheetTrigger, SheetTitle } from \"../ui/sheet\";\nimport { ChatInterface } from \"./ChatInterface\";\nimport { MessageCircle } from \"lucide-react\";\n// TODO: @radix-ui/react-visually-hidden — keep as peer dep.\nimport * as VisuallyHidden from \"@radix-ui/react-visually-hidden\";\n\ninterface ChatDrawerProps {\n\tdefaultOpen?: boolean;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\ttrigger?: React.ReactNode;\n\thideTrigger?: boolean;\n}\n\nexport function ChatDrawer({\n\tdefaultOpen = false,\n\topen: controlledOpen,\n\tonOpenChange,\n\ttrigger,\n\thideTrigger = false,\n}: ChatDrawerProps) {\n\tconst [internalOpen, setInternalOpen] = useState(defaultOpen);\n\n\tconst isControlled = controlledOpen !== undefined;\n\tconst isOpen = isControlled ? controlledOpen : internalOpen;\n\n\tconst handleOpenChange = (open: boolean) => {\n\t\tif (!isControlled) setInternalOpen(open);\n\t\tonOpenChange?.(open);\n\t};\n\n\tuseEffect(() => {\n\t\tif (typeof document === \"undefined\") return;\n\t\tconst handleCloseChat = () => handleOpenChange(false);\n\t\tdocument.addEventListener(\"aigentyc:close-chat\", handleCloseChat);\n\t\treturn () => document.removeEventListener(\"aigentyc:close-chat\", handleCloseChat);\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, []);\n\n\treturn (\n\t\t<Sheet open={isOpen} onOpenChange={handleOpenChange}>\n\t\t\t{!hideTrigger && (\n\t\t\t\t<SheetTrigger asChild>\n\t\t\t\t\t{trigger || (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"fixed bottom-6 right-6 z-40 flex h-14 w-14 items-center justify-center rounded-full shadow-lg transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2\"\n\t\t\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary)\", color: \"var(--ac-primary-foreground, #fff)\" }}\n\t\t\t\t\t\t\taria-label=\"Open chat\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<MessageCircle className=\"h-6 w-6\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</SheetTrigger>\n\t\t\t)}\n\t\t\t<SheetContent\n\t\t\t\tside=\"right\"\n\t\t\t\tclassName=\"w-full sm:w-[450px] sm:max-w-[450px] p-0 flex flex-col [&>button]:hidden\"\n\t\t\t>\n\t\t\t\t<VisuallyHidden.Root>\n\t\t\t\t\t<SheetTitle>Chat Assistant</SheetTitle>\n\t\t\t\t</VisuallyHidden.Root>\n\t\t\t\t<ChatInterface />\n\t\t\t</SheetContent>\n\t\t</Sheet>\n\t);\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useI18n } from \"../hooks/use-i18n\";\n\ninterface VisitorIdentityFormProps {\n\tonSubmit: (name: string, email: string) => void;\n\tonCancel: () => void;\n}\n\nexport function VisitorIdentityForm({ onSubmit, onCancel }: VisitorIdentityFormProps) {\n\tconst [name, setName] = useState(\"\");\n\tconst [email, setEmail] = useState(\"\");\n\tconst { t, direction } = useI18n();\n\tconst isRTL = direction === \"rtl\";\n\n\treturn (\n\t\t<div className=\"border-t bg-blue-50/80 px-4 py-4\" dir={isRTL ? \"rtl\" : \"ltr\"}>\n\t\t\t<p className=\"text-sm text-blue-800 font-medium mb-3\">{t(\"liveChatIdentityTitle\")}</p>\n\t\t\t<div className=\"space-y-2\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(e) => setName(e.target.value)}\n\t\t\t\t\tplaceholder={t(\"liveChatIdentityName\")}\n\t\t\t\t\tclassName=\"w-full text-sm p-2.5 border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-blue-300\"\n\t\t\t\t\tautoFocus\n\t\t\t\t/>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"email\"\n\t\t\t\t\tvalue={email}\n\t\t\t\t\tonChange={(e) => setEmail(e.target.value)}\n\t\t\t\t\tplaceholder={t(\"liveChatIdentityEmail\")}\n\t\t\t\t\tclassName=\"w-full text-sm p-2.5 border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-blue-300\"\n\t\t\t\t/>\n\t\t\t\t<div className=\"flex gap-2 justify-end\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\tclassName=\"text-sm text-muted-foreground hover:text-foreground px-4 py-2 rounded-lg\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"liveChatCancel\")}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => onSubmit(name, email)}\n\t\t\t\t\t\tdisabled={!name.trim() || !email.trim()}\n\t\t\t\t\t\tclassName=\"text-sm text-white px-5 py-2 rounded-lg disabled:opacity-40\"\n\t\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary, #2f80ed)\" }}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"liveChatIdentityConnect\")}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\ninterface LiveChatHeaderProps {\n\toperatorName: string;\n\tonEndChat: () => void;\n}\n\nexport function LiveChatHeader({ operatorName, onEndChat }: LiveChatHeaderProps) {\n\treturn (\n\t\t<div className=\"bg-green-50 border-b border-green-200 px-4 py-2 flex items-center justify-between\">\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<div className=\"h-2 w-2 rounded-full bg-green-500\" />\n\t\t\t\t<span className=\"text-sm text-green-800 font-medium\">Chatting with {operatorName}</span>\n\t\t\t</div>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onEndChat}\n\t\t\t\tclassName=\"text-xs text-red-600 hover:text-red-800 bg-red-50 px-2 py-1 rounded\"\n\t\t\t>\n\t\t\t\tEnd Chat\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\ninterface QueueBannerProps {\n\tposition: number;\n\tonCancel: () => void;\n}\n\nexport function LiveChatQueueBanner({ position, onCancel }: QueueBannerProps) {\n\treturn (\n\t\t<div className=\"bg-blue-50 border-b border-blue-200 px-4 py-3 flex items-center justify-between\">\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<div className=\"h-2 w-2 rounded-full bg-blue-500 animate-pulse\" />\n\t\t\t\t<span className=\"text-sm text-blue-800\">\n\t\t\t\t\tConnecting you with an operator...\n\t\t\t\t\t{position > 0 && <span className=\"font-medium\"> Position #{position}</span>}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onCancel}\n\t\t\t\tclassName=\"text-xs text-blue-600 hover:text-blue-800 underline\"\n\t\t\t>\n\t\t\t\tCancel\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { ThumbsUp, ThumbsDown } from \"lucide-react\";\n\ninterface SatisfactionRatingProps {\n\tonSubmit: (rating: \"positive\" | \"negative\", comment?: string) => void;\n\tonSkip: () => void;\n}\n\nexport function SatisfactionRating({ onSubmit, onSkip }: SatisfactionRatingProps) {\n\tconst [selected, setSelected] = useState<\"positive\" | \"negative\" | null>(null);\n\tconst [comment, setComment] = useState(\"\");\n\tconst [submitted, setSubmitted] = useState(false);\n\n\tif (submitted) {\n\t\treturn (\n\t\t\t<div className=\"bg-secondary/50 border-t px-4 py-3 text-center\">\n\t\t\t\t<p className=\"text-sm text-muted-foreground\">Thank you for your feedback!</p>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={onSkip}\n\t\t\t\t\tclassName=\"text-xs text-blue-600 hover:underline mt-1\"\n\t\t\t\t>\n\t\t\t\t\tBack to AI Assistant\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"bg-secondary/50 border-t px-4 py-3\">\n\t\t\t<p className=\"text-sm text-foreground/80 text-center mb-2\">How was your experience?</p>\n\t\t\t<div className=\"flex justify-center gap-4 mb-2\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={() => setSelected(\"positive\")}\n\t\t\t\t\tclassName={`p-2 rounded-full transition-colors ${\n\t\t\t\t\t\tselected === \"positive\" ? \"bg-green-100 text-green-600\" : \"hover:bg-muted text-muted-foreground\"\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t<ThumbsUp className=\"h-5 w-5\" />\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={() => setSelected(\"negative\")}\n\t\t\t\t\tclassName={`p-2 rounded-full transition-colors ${\n\t\t\t\t\t\tselected === \"negative\" ? \"bg-red-100 text-red-600\" : \"hover:bg-muted text-muted-foreground\"\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t<ThumbsDown className=\"h-5 w-5\" />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t{selected && (\n\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t<textarea\n\t\t\t\t\t\tvalue={comment}\n\t\t\t\t\t\tonChange={(e) => setComment(e.target.value)}\n\t\t\t\t\t\tplaceholder=\"Any additional feedback? (optional)\"\n\t\t\t\t\t\tclassName=\"w-full text-xs p-2 border rounded resize-none h-16\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"flex justify-center gap-2\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tonSubmit(selected, comment || undefined);\n\t\t\t\t\t\t\t\tsetSubmitted(true);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclassName=\"text-xs text-white px-3 py-1 rounded\"\n\t\t\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary)\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSubmit\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={onSkip}\n\t\t\t\t\t\t\tclassName=\"text-xs text-muted-foreground hover:underline px-3 py-1\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSkip\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!selected && (\n\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onSkip}\n\t\t\t\t\t\tclassName=\"text-xs text-muted-foreground hover:underline\"\n\t\t\t\t\t>\n\t\t\t\t\t\tSkip\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ChatInputWithAttachments.tsx","../src/ui/sheet.tsx","../src/components/ChatDrawer.tsx","../src/components/VisitorIdentityForm.tsx","../src/components/LiveChatHeader.tsx","../src/components/LiveChatQueueBanner.tsx","../src/components/SatisfactionRating.tsx"],"names":["jsx","jsxs","X","useState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBO,SAAS,wBAAA,CAAyB;AAAA,EACxC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,GAAe,KAAA;AAAA,EACf,WAAA,GAAc;AACf,CAAA,EAAkC;AACjC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,CAAuB,EAAE,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,OAAyB,IAAI,CAAA;AAElD,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA6C;AACnE,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,KAAY,KAAA,CAAM,IAAA,MAAU,WAAA,CAAY,MAAA,GAAS,CAAA,CAAA,IAAM,CAAC,YAAA,EAAc;AACnF,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,YAAA,EAAa;AAAA,IACd;AAAA,EACD,CAAA;AAEA,EAAA,MAAM,eAAe,MAAM;AAC1B,IAAA,IAAK,CAAC,KAAA,CAAM,IAAA,MAAU,WAAA,CAAY,MAAA,KAAW,KAAM,YAAA,EAAc;AACjE,IAAA,MAAM,SAAA,GAA0B,WAAA,CAAY,GAAA,CAAI,CAAC,EAAE,IAAI,GAAA,EAAK,GAAG,IAAA,EAAK,KAAM,IAAI,CAAA;AAC9E,IAAA,QAAA,CAAS,KAAA,EAAO,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,YAAY,MAAS,CAAA;AAC5D,IAAA,cAAA,CAAe,EAAE,CAAA;AAAA,EAClB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,CAAA,KAA2C;AAC1E,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,CAAO,KAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,MAAM,iBAA+B,EAAC;AAEtC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,EAAG;AACrC,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,EAAG;AACrC,MAAA,MAAM,OAAA,GAAU,MAAM,aAAA,CAAc,IAAI,CAAA;AACxC,MAAA,cAAA,CAAe,IAAA,CAAK;AAAA,QACnB,EAAA,EAAI,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAAA,QACxD,IAAA,EAAM,MAAA;AAAA,QACN,GAAA,EAAK,OAAA;AAAA,QACL,WAAW,IAAA,CAAK,IAAA;AAAA,QAChB,UAAU,IAAA,CAAK;AAAA,OACf,CAAA;AAAA,IACF;AAEA,IAAA,cAAA,CAAe,CAAC,IAAA,KAAS,CAAC,GAAG,IAAA,EAAM,GAAG,cAAc,CAAC,CAAA;AACrD,IAAA,CAAA,CAAE,OAAO,KAAA,GAAQ,EAAA;AAAA,EAClB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,EAAA,KAAe;AACxC,IAAA,cAAA,CAAe,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AAAA,EACzD,CAAA;AAEA,EAAA,MAAM,iBAAiB,MAAM;AAC5B,IAAA,YAAA,CAAa,SAAS,KAAA,EAAM;AAAA,EAC7B,CAAA;AAEA,EAAA,uBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,IAAA,WAAA,CAAY,MAAA,GAAS,qBACrB,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2BAAA,EACb,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,UAAA,qBACjB,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEA,SAAA,EAAU,+DAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACA,KAAK,UAAA,CAAW,GAAA;AAAA,cAChB,GAAA,EAAK,WAAW,QAAA,IAAY,YAAA;AAAA,cAC5B,SAAA,EAAU;AAAA;AAAA,WACX;AAAA,0BACA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,MAAM,gBAAA,CAAiB,UAAA,CAAW,EAAE,CAAA;AAAA,cAC7C,SAAA,EAAU,0JAAA;AAAA,cAEV,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AACxB;AAAA,OAAA;AAAA,MAdK,UAAA,CAAW;AAAA,KAgBjB,CAAA,EACF,CAAA;AAAA,oBAGD,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,SAAA,EAAU,wGAAA;AAAA,QACV,KAAA,EAAO,EAAE,eAAA,EAAiB,sBAAA,EAAwB,aAAa,kBAAA,EAAmB;AAAA,QAElF,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,cAAA;AAAA,cACT,QAAA,EAAU,YAAA;AAAA,cACV,SAAA,EAAU,4JAAA;AAAA,cACV,KAAA,EAAM,cAAA;AAAA,cAEN,QAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,WAChC;AAAA,0BAEA,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACA,GAAA,EAAK,YAAA;AAAA,cACL,IAAA,EAAK,MAAA;AAAA,cACL,MAAA,EAAO,SAAA;AAAA,cACP,QAAA,EAAQ,IAAA;AAAA,cACR,QAAA,EAAU,gBAAA;AAAA,cACV,SAAA,EAAU;AAAA;AAAA,WACX;AAAA,0BAEA,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,MAAA;AAAA,cACL,KAAA;AAAA,cACA,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cACxC,SAAA,EAAW,aAAA;AAAA,cACX,QAAA,EAAU,YAAA;AAAA,cACV,WAAA;AAAA,cACA,SAAA,EAAU,+FAAA;AAAA,cACV,KAAA,EAAO,EAAE,KAAA,EAAO,gBAAA;AAAiB;AAAA,WAClC;AAAA,0BAEA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACA,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,YAAA;AAAA,cACT,UAAW,CAAC,KAAA,CAAM,MAAK,IAAK,WAAA,CAAY,WAAW,CAAA,IAAM,YAAA;AAAA,cACzD,SAAA,EAAU,4JAAA;AAAA,cACV,KAAA,EAAO,EAAE,eAAA,EAAiB,mBAAA,EAAqB,OAAO,oCAAA,EAAqC;AAAA,cAE1F,QAAA,EAAA,YAAA,uBACC,MAAA,EAAA,EAAO,SAAA,EAAU,sBAAqB,CAAA,mBAEvC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EAAwB,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,OAAM,4BAAA,EAC5E,QAAA,kBAAA,GAAA,CAAC,UAAK,CAAA,EAAE,+ZAAA,EAAga,IAAA,EAAK,OAAA,EAAQ,CAAA,EACtb;AAAA;AAAA;AAEF;AAAA;AAAA;AACD,GAAA,EACD,CAAA;AAEF;AAEA,eAAe,cAAc,IAAA,EAA6B;AACzD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACvC,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAC9B,IAAA,MAAA,CAAO,MAAA,GAAS,MAAM,OAAA,CAAQ,MAAA,CAAO,MAAgB,CAAA;AACrD,IAAA,MAAA,CAAO,OAAA,GAAU,MAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,EAC1B,CAAC,CAAA;AACF;AC3JA,IAAM,KAAA,GAAuB,cAAA,CAAA,IAAA;AAE7B,IAAM,YAAA,GAA8B,cAAA,CAAA,OAAA;AAIpC,IAAM,WAAA,GAA6B,cAAA,CAAA,MAAA;AAEnC,IAAM,YAAA,GAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAgB,cAAA,CAAA,OAAA;AAAA,EAAf;AAAA,IACC,SAAA,EAAW,EAAA;AAAA,MACT,yJAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG,KAAA;AAAA,IACJ;AAAA;AACF,CACD,CAAA;AACD,YAAA,CAAa,cAA6B,cAAA,CAAA,OAAA,CAAQ,WAAA;AAElD,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,kMAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM;AAAA,QACJ,GAAA,EAAK,mGAAA;AAAA,QACL,MAAA,EACE,4GAAA;AAAA,QACF,IAAA,EAAM,+HAAA;AAAA,QACN,KAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AAQA,IAAM,eAAqB,KAAA,CAAA,UAAA,CAGzB,CAAC,EAAE,IAAA,GAAO,SAAS,SAAA,EAAW,QAAA,EAAU,cAAA,EAAgB,eAAA,EAAiB,GAAG,KAAA,EAAM,EAAG,GAAA,qBACrFC,KAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,kBAAAD,IAAC,YAAA,EAAA,EAAa,CAAA;AAAA,kBACdC,IAAAA;AAAA,IAAgB,cAAA,CAAA,OAAA;AAAA,IAAf;AAAA,MACC,GAAA;AAAA,MACA,WAAW,EAAA,CAAG,aAAA,CAAc,EAAE,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MAC/C,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAA,IAAAA,CAAgB,cAAA,CAAA,KAAA,EAAf,EAAqB,SAAA,EAAU,0OAAA,EAC9B,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAACE,CAAAA,EAAA,EAAE,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,0BACvBF,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,OAAA,EAAK;AAAA,SAAA,EACjC,CAAA;AAAA,QACC;AAAA;AAAA;AAAA;AACH,CAAA,EACF,CACD,CAAA;AACD,YAAA,CAAa,cAA6B,cAAA,CAAA,OAAA,CAAQ,WAAA;AA8BlD,IAAM,UAAA,GAAmB,iBAGvB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAgB,cAAA,CAAA,KAAA;AAAA,EAAf;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,IAC/D,GAAG;AAAA;AACN,CACD,CAAA;AACD,UAAA,CAAW,cAA6B,cAAA,CAAA,KAAA,CAAM,WAAA;AAE9C,IAAM,gBAAA,GAAyB,iBAG7B,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAgB,cAAA,CAAA,WAAA;AAAA,EAAf;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,IACvD,GAAG;AAAA;AACN,CACD,CAAA;AACD,gBAAA,CAAiB,cAA6B,cAAA,CAAA,WAAA,CAAY,WAAA;AC/GnD,SAAS,UAAA,CAAW;AAAA,EAC1B,WAAA,GAAc,KAAA;AAAA,EACd,IAAA,EAAM,cAAA;AAAA,EACN,YAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA,GAAc;AACf,CAAA,EAAoB;AACnB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIG,SAAS,WAAW,CAAA;AAE5D,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,MAAA,GAAS,eAAe,cAAA,GAAiB,YAAA;AAE/C,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAAkB;AAC3C,IAAA,IAAI,CAAC,YAAA,EAAc,eAAA,CAAgB,IAAI,CAAA;AACvC,IAAA,YAAA,GAAe,IAAI,CAAA;AAAA,EACpB,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACf,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,IAAA,MAAM,eAAA,GAAkB,MAAM,gBAAA,CAAiB,KAAK,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,uBAAuB,eAAe,CAAA;AAChE,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,qBAAA,EAAuB,eAAe,CAAA;AAAA,EAEjF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,uBACCF,IAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,cAAc,gBAAA,EACjC,QAAA,EAAA;AAAA,IAAA,CAAC,+BACDD,GAAAA,CAAC,gBAAa,OAAA,EAAO,IAAA,EACnB,qCACAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,wLAAA;AAAA,QACV,KAAA,EAAO,EAAE,eAAA,EAAiB,mBAAA,EAAqB,OAAO,oCAAA,EAAqC;AAAA,QAC3F,YAAA,EAAW,WAAA;AAAA,QAEX,QAAA,kBAAAA,GAAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,KACpC,EAEF,CAAA;AAAA,oBAEDC,IAAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,EAAU,0EAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAD,IAAgB,cAAA,CAAA,IAAA,EAAf,EACA,0BAAAA,GAAAA,CAAC,UAAA,EAAA,EAAW,4BAAc,CAAA,EAC3B,CAAA;AAAA,0BACAA,IAAC,aAAA,EAAA,EAAc;AAAA;AAAA;AAAA;AAChB,GAAA,EACD,CAAA;AAEF;AC3DO,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAU,QAAA,EAAS,EAA6B;AACrF,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIG,SAAS,EAAE,CAAA;AACnC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAS,EAAE,CAAA;AACrC,EAAA,MAAM,EAAE,CAAA,EAAG,SAAA,EAAU,GAAI,OAAA,EAAQ;AACjC,EAAA,MAAM,QAAQ,SAAA,KAAc,KAAA;AAE5B,EAAA,uBACCF,KAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAmC,GAAA,EAAK,KAAA,GAAQ,QAAQ,KAAA,EACtE,QAAA,EAAA;AAAA,oBAAAD,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAA,EAA0C,QAAA,EAAA,CAAA,CAAE,uBAAuB,CAAA,EAAE,CAAA;AAAA,oBAClFC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,MAAA;AAAA,UACL,KAAA,EAAO,IAAA;AAAA,UACP,UAAU,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,UACvC,WAAA,EAAa,EAAE,sBAAsB,CAAA;AAAA,UACrC,SAAA,EAAU,0GAAA;AAAA,UACV,SAAA,EAAS;AAAA;AAAA,OACV;AAAA,sBACAA,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,OAAA;AAAA,UACL,KAAA,EAAO,KAAA;AAAA,UACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,UACxC,WAAA,EAAa,EAAE,uBAAuB,CAAA;AAAA,UACtC,SAAA,EAAU;AAAA;AAAA,OACX;AAAA,sBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACd,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,QAAA;AAAA,YACT,SAAA,EAAU,0EAAA;AAAA,YAET,YAAE,gBAAgB;AAAA;AAAA,SACpB;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AAAA,YACnC,UAAU,CAAC,IAAA,CAAK,MAAK,IAAK,CAAC,MAAM,IAAA,EAAK;AAAA,YACtC,SAAA,EAAU,6DAAA;AAAA,YACV,KAAA,EAAO,EAAE,eAAA,EAAiB,4BAAA,EAA6B;AAAA,YAEtD,YAAE,yBAAyB;AAAA;AAAA;AAC7B,OAAA,EACD;AAAA,KAAA,EACD;AAAA,GAAA,EACD,CAAA;AAEF;ACjDO,SAAS,cAAA,CAAe,EAAE,YAAA,EAAc,SAAA,EAAU,EAAwB;AAChF,EAAA,uBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mFAAA,EACd,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAA,EAAoC,CAAA;AAAA,sBACnDC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oCAAA,EAAqC,QAAA,EAAA;AAAA,QAAA,gBAAA;AAAA,QAAe;AAAA,OAAA,EAAa;AAAA,KAAA,EAClF,CAAA;AAAA,oBACAD,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,SAAA;AAAA,QACT,SAAA,EAAU,qEAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EACD,CAAA;AAEF;AChBO,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAU,QAAA,EAAS,EAAqB;AAC7E,EAAA,uBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iFAAA,EACd,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EAAiD,CAAA;AAAA,sBAChEC,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA;AAAA,QAAA,oCAAA;AAAA,QAEtC,WAAW,CAAA,oBAAKA,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,aAAA,EAAc,QAAA,EAAA;AAAA,UAAA,aAAA;AAAA,UAAY;AAAA,SAAA,EAAS;AAAA,OAAA,EACrE;AAAA,KAAA,EACD,CAAA;AAAA,oBACAD,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,QAAA;AAAA,QACT,SAAA,EAAU,qDAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EACD,CAAA;AAEF;AChBO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAU,MAAA,EAAO,EAA4B;AACjF,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIG,SAAyC,IAAI,CAAA;AAC7E,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,SAAS,EAAE,CAAA;AACzC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAS,KAAK,CAAA;AAEhD,EAAA,IAAI,SAAA,EAAW;AACd,IAAA,uBACCF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+BAAA,EAAgC,QAAA,EAAA,8BAAA,EAA4B,CAAA;AAAA,sBACzEA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,MAAA;AAAA,UACT,SAAA,EAAU,4CAAA;AAAA,UACV,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACD,CAAA;AAAA,EAEF;AAEA,EAAA,uBACCC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACd,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6CAAA,EAA8C,QAAA,EAAA,0BAAA,EAAwB,CAAA;AAAA,oBACnFC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,MAAM,WAAA,CAAY,UAAU,CAAA;AAAA,UACrC,SAAA,EAAW,CAAA,mCAAA,EACV,QAAA,KAAa,UAAA,GAAa,gCAAgC,sCAC3D,CAAA,CAAA;AAAA,UAEA,QAAA,kBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,OAC/B;AAAA,sBACAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,OAAA,EAAS,MAAM,WAAA,CAAY,UAAU,CAAA;AAAA,UACrC,SAAA,EAAW,CAAA,mCAAA,EACV,QAAA,KAAa,UAAA,GAAa,4BAA4B,sCACvD,CAAA,CAAA;AAAA,UAEA,QAAA,kBAAAA,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AACjC,KAAA,EACD,CAAA;AAAA,IACC,QAAA,oBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,WAAA,EACd,QAAA,EAAA;AAAA,sBAAAD,GAAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACA,KAAA,EAAO,OAAA;AAAA,UACP,UAAU,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,UAC1C,WAAA,EAAY,qCAAA;AAAA,UACZ,SAAA,EAAU;AAAA;AAAA,OACX;AAAA,sBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACd,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,SAAS,MAAM;AACd,cAAA,QAAA,CAAS,QAAA,EAAU,WAAW,MAAS,CAAA;AACvC,cAAA,YAAA,CAAa,IAAI,CAAA;AAAA,YAClB,CAAA;AAAA,YACA,SAAA,EAAU,sCAAA;AAAA,YACV,KAAA,EAAO,EAAE,eAAA,EAAiB,mBAAA,EAAoB;AAAA,YAC9C,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACA,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAA;AAAA,YACT,SAAA,EAAU,yDAAA;AAAA,YACV,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACD;AAAA,KAAA,EACD,CAAA;AAAA,IAEA,CAAC,QAAA,oBACDA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eACd,QAAA,kBAAAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAU,+CAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA,KAED,EACD;AAAA,GAAA,EAEF,CAAA;AAEF","file":"components.js","sourcesContent":["\"use client\";\n\n/**\n * Chat Input with Image Attachments - Enhanced input for kitchen image analysis\n */\n\nimport { useRef, useState } from \"react\";\nimport { ImageIcon, Square, X } from \"lucide-react\";\n// TODO: `FileUIPart` imported from \"ai\" (Vercel AI SDK). Make sure `ai` is installed as peer dependency.\nimport type { FileUIPart } from \"ai\";\n\ninterface Attachment extends FileUIPart {\n\tid: string;\n}\n\ninterface ChatInputWithAttachmentsProps {\n\tvalue: string;\n\tonChange: (value: string) => void;\n\tonSubmit: (text: string, attachments?: FileUIPart[]) => void;\n\tisProcessing?: boolean;\n\tplaceholder?: string;\n}\n\nexport function ChatInputWithAttachments({\n\tvalue,\n\tonChange,\n\tonSubmit,\n\tisProcessing = false,\n\tplaceholder = \"Ask anything or upload an image...\",\n}: ChatInputWithAttachmentsProps) {\n\tconst [attachments, setAttachments] = useState<Attachment[]>([]);\n\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\n\tconst handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\tif (e.key === \"Enter\" && (value.trim() || attachments.length > 0) && !isProcessing) {\n\t\t\te.preventDefault();\n\t\t\thandleSubmit();\n\t\t}\n\t};\n\n\tconst handleSubmit = () => {\n\t\tif ((!value.trim() && attachments.length === 0) || isProcessing) return;\n\t\tconst fileParts: FileUIPart[] = attachments.map(({ id: _id, ...rest }) => rest);\n\t\tonSubmit(value, fileParts.length > 0 ? fileParts : undefined);\n\t\tsetAttachments([]);\n\t};\n\n\tconst handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\tconst files = e.target.files;\n\t\tif (!files) return;\n\n\t\tconst newAttachments: Attachment[] = [];\n\n\t\tfor (const file of Array.from(files)) {\n\t\t\tif (!file.type.startsWith(\"image/\")) continue;\n\t\t\tconst dataUrl = await fileToDataUrl(file);\n\t\t\tnewAttachments.push({\n\t\t\t\tid: `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n\t\t\t\ttype: \"file\",\n\t\t\t\turl: dataUrl,\n\t\t\t\tmediaType: file.type,\n\t\t\t\tfilename: file.name,\n\t\t\t});\n\t\t}\n\n\t\tsetAttachments((prev) => [...prev, ...newAttachments]);\n\t\te.target.value = \"\";\n\t};\n\n\tconst removeAttachment = (id: string) => {\n\t\tsetAttachments((prev) => prev.filter((a) => a.id !== id));\n\t};\n\n\tconst openFileDialog = () => {\n\t\tfileInputRef.current?.click();\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t{attachments.length > 0 && (\n\t\t\t\t<div className=\"flex flex-wrap gap-2 px-4\">\n\t\t\t\t\t{attachments.map((attachment) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={attachment.id}\n\t\t\t\t\t\t\tclassName=\"relative group rounded-lg overflow-hidden border bg-secondary\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tsrc={attachment.url}\n\t\t\t\t\t\t\t\talt={attachment.filename || \"Attachment\"}\n\t\t\t\t\t\t\t\tclassName=\"h-16 w-16 object-cover\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => removeAttachment(attachment.id)}\n\t\t\t\t\t\t\t\tclassName=\"absolute top-1 right-1 w-5 h-5 rounded-full bg-black/60 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<X className=\"w-3 h-3\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div\n\t\t\t\tclassName=\"flex items-center gap-2 backdrop-blur-xl border shadow-xl rounded-full pl-3 md:pl-4 pr-1.5 md:pr-[6px]\"\n\t\t\t\tstyle={{ backgroundColor: \"var(--ac-background)\", borderColor: \"var(--ac-border)\" }}\n\t\t\t>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={openFileDialog}\n\t\t\t\t\tdisabled={isProcessing}\n\t\t\t\t\tclassName=\"flex items-center justify-center w-9 h-9 rounded-full text-muted-foreground hover:text-foreground hover:bg-secondary transition-colors disabled:opacity-50\"\n\t\t\t\t\ttitle=\"Upload image\"\n\t\t\t\t>\n\t\t\t\t\t<ImageIcon className=\"w-5 h-5\" />\n\t\t\t\t</button>\n\n\t\t\t\t<input\n\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\taccept=\"image/*\"\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={handleFileSelect}\n\t\t\t\t\tclassName=\"hidden\"\n\t\t\t\t/>\n\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tonChange={(e) => onChange(e.target.value)}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\tdisabled={isProcessing}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tclassName=\"flex-1 bg-transparent outline-none text-base min-h-[56px] md:min-h-[69px] disabled:opacity-50\"\n\t\t\t\t\tstyle={{ color: \"var(--ac-text)\" }}\n\t\t\t\t/>\n\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={handleSubmit}\n\t\t\t\t\tdisabled={(!value.trim() && attachments.length === 0) || isProcessing}\n\t\t\t\t\tclassName=\"flex items-center justify-center w-11 h-11 md:w-[55px] md:h-[55px] rounded-full disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0\"\n\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary)\", color: \"var(--ac-primary-foreground, #fff)\" }}\n\t\t\t\t>\n\t\t\t\t\t{isProcessing ? (\n\t\t\t\t\t\t<Square className=\"w-5 h-5 fill-white\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<svg className=\"w-6 h-6 md:w-7 md:h-7\" viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t\t\t<path d=\"M2 15C1.44772 15 1 14.5523 1 14C1 13.4477 1.44772 13 2 13V14L2 15ZM26.7071 13.2929C27.0976 13.6834 27.0976 14.3166 26.7071 14.7071L20.3431 21.0711C19.9526 21.4616 19.3195 21.4616 18.9289 21.0711C18.5384 20.6805 18.5384 20.0474 18.9289 19.6569L24.5858 14L18.9289 8.34315C18.5384 7.95262 18.5384 7.31946 18.9289 6.92893C19.3195 6.53841 19.9526 6.53841 20.3431 6.92893L26.7071 13.2929ZM2 14V13L26 13V14V15L2 15L2 14Z\" fill=\"white\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nasync function fileToDataUrl(file: File): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader();\n\t\treader.onload = () => resolve(reader.result as string);\n\t\treader.onerror = reject;\n\t\treader.readAsDataURL(file);\n\t});\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"../core/utils\"\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst SheetPortal = SheetPrimitive.Portal\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n ref={ref}\n />\n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out\",\n {\n variants: {\n side: {\n top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n bottom:\n \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n right:\n \"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n },\n },\n defaultVariants: {\n side: \"right\",\n },\n }\n)\n\ninterface SheetContentProps\n extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n VariantProps<typeof sheetVariants> {\n overlayVariant?: \"default\" | \"light\";\n}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n SheetContentProps\n>(({ side = \"right\", className, children, overlayVariant: _overlayVariant, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n {children}\n </SheetPrimitive.Content>\n </SheetPortal>\n))\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-start\",\n className\n )}\n {...props}\n />\n)\nSheetHeader.displayName = \"SheetHeader\"\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nSheetFooter.displayName = \"SheetFooter\"\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold text-foreground\", className)}\n {...props}\n />\n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { Sheet, SheetContent, SheetTrigger, SheetTitle } from \"../ui/sheet\";\nimport { ChatInterface } from \"./ChatInterface\";\nimport { MessageCircle } from \"lucide-react\";\n// TODO: @radix-ui/react-visually-hidden — keep as peer dep.\nimport * as VisuallyHidden from \"@radix-ui/react-visually-hidden\";\n\ninterface ChatDrawerProps {\n\tdefaultOpen?: boolean;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\ttrigger?: React.ReactNode;\n\thideTrigger?: boolean;\n}\n\nexport function ChatDrawer({\n\tdefaultOpen = false,\n\topen: controlledOpen,\n\tonOpenChange,\n\ttrigger,\n\thideTrigger = false,\n}: ChatDrawerProps) {\n\tconst [internalOpen, setInternalOpen] = useState(defaultOpen);\n\n\tconst isControlled = controlledOpen !== undefined;\n\tconst isOpen = isControlled ? controlledOpen : internalOpen;\n\n\tconst handleOpenChange = (open: boolean) => {\n\t\tif (!isControlled) setInternalOpen(open);\n\t\tonOpenChange?.(open);\n\t};\n\n\tuseEffect(() => {\n\t\tif (typeof document === \"undefined\") return;\n\t\tconst handleCloseChat = () => handleOpenChange(false);\n\t\tdocument.addEventListener(\"aigentyc:close-chat\", handleCloseChat);\n\t\treturn () => document.removeEventListener(\"aigentyc:close-chat\", handleCloseChat);\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, []);\n\n\treturn (\n\t\t<Sheet open={isOpen} onOpenChange={handleOpenChange}>\n\t\t\t{!hideTrigger && (\n\t\t\t\t<SheetTrigger asChild>\n\t\t\t\t\t{trigger || (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"fixed bottom-6 right-6 z-40 flex h-14 w-14 items-center justify-center rounded-full shadow-lg transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2\"\n\t\t\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary)\", color: \"var(--ac-primary-foreground, #fff)\" }}\n\t\t\t\t\t\t\taria-label=\"Open chat\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<MessageCircle className=\"h-6 w-6\" />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</SheetTrigger>\n\t\t\t)}\n\t\t\t<SheetContent\n\t\t\t\tside=\"right\"\n\t\t\t\tclassName=\"w-full sm:w-[450px] sm:max-w-[450px] p-0 flex flex-col [&>button]:hidden\"\n\t\t\t>\n\t\t\t\t<VisuallyHidden.Root>\n\t\t\t\t\t<SheetTitle>Chat Assistant</SheetTitle>\n\t\t\t\t</VisuallyHidden.Root>\n\t\t\t\t<ChatInterface />\n\t\t\t</SheetContent>\n\t\t</Sheet>\n\t);\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useI18n } from \"../hooks/use-i18n\";\n\ninterface VisitorIdentityFormProps {\n\tonSubmit: (name: string, email: string) => void;\n\tonCancel: () => void;\n}\n\nexport function VisitorIdentityForm({ onSubmit, onCancel }: VisitorIdentityFormProps) {\n\tconst [name, setName] = useState(\"\");\n\tconst [email, setEmail] = useState(\"\");\n\tconst { t, direction } = useI18n();\n\tconst isRTL = direction === \"rtl\";\n\n\treturn (\n\t\t<div className=\"border-t bg-blue-50/80 px-4 py-4\" dir={isRTL ? \"rtl\" : \"ltr\"}>\n\t\t\t<p className=\"text-sm text-blue-800 font-medium mb-3\">{t(\"liveChatIdentityTitle\")}</p>\n\t\t\t<div className=\"space-y-2\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(e) => setName(e.target.value)}\n\t\t\t\t\tplaceholder={t(\"liveChatIdentityName\")}\n\t\t\t\t\tclassName=\"w-full text-sm p-2.5 border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-blue-300\"\n\t\t\t\t\tautoFocus\n\t\t\t\t/>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"email\"\n\t\t\t\t\tvalue={email}\n\t\t\t\t\tonChange={(e) => setEmail(e.target.value)}\n\t\t\t\t\tplaceholder={t(\"liveChatIdentityEmail\")}\n\t\t\t\t\tclassName=\"w-full text-sm p-2.5 border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-blue-300\"\n\t\t\t\t/>\n\t\t\t\t<div className=\"flex gap-2 justify-end\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\tclassName=\"text-sm text-muted-foreground hover:text-foreground px-4 py-2 rounded-lg\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"liveChatCancel\")}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => onSubmit(name, email)}\n\t\t\t\t\t\tdisabled={!name.trim() || !email.trim()}\n\t\t\t\t\t\tclassName=\"text-sm text-white px-5 py-2 rounded-lg disabled:opacity-40\"\n\t\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary, #2f80ed)\" }}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"liveChatIdentityConnect\")}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\ninterface LiveChatHeaderProps {\n\toperatorName: string;\n\tonEndChat: () => void;\n}\n\nexport function LiveChatHeader({ operatorName, onEndChat }: LiveChatHeaderProps) {\n\treturn (\n\t\t<div className=\"bg-green-50 border-b border-green-200 px-4 py-2 flex items-center justify-between\">\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<div className=\"h-2 w-2 rounded-full bg-green-500\" />\n\t\t\t\t<span className=\"text-sm text-green-800 font-medium\">Chatting with {operatorName}</span>\n\t\t\t</div>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onEndChat}\n\t\t\t\tclassName=\"text-xs text-red-600 hover:text-red-800 bg-red-50 px-2 py-1 rounded\"\n\t\t\t>\n\t\t\t\tEnd Chat\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\ninterface QueueBannerProps {\n\tposition: number;\n\tonCancel: () => void;\n}\n\nexport function LiveChatQueueBanner({ position, onCancel }: QueueBannerProps) {\n\treturn (\n\t\t<div className=\"bg-blue-50 border-b border-blue-200 px-4 py-3 flex items-center justify-between\">\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<div className=\"h-2 w-2 rounded-full bg-blue-500 animate-pulse\" />\n\t\t\t\t<span className=\"text-sm text-blue-800\">\n\t\t\t\t\tConnecting you with an operator...\n\t\t\t\t\t{position > 0 && <span className=\"font-medium\"> Position #{position}</span>}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={onCancel}\n\t\t\t\tclassName=\"text-xs text-blue-600 hover:text-blue-800 underline\"\n\t\t\t>\n\t\t\t\tCancel\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { ThumbsUp, ThumbsDown } from \"lucide-react\";\n\ninterface SatisfactionRatingProps {\n\tonSubmit: (rating: \"positive\" | \"negative\", comment?: string) => void;\n\tonSkip: () => void;\n}\n\nexport function SatisfactionRating({ onSubmit, onSkip }: SatisfactionRatingProps) {\n\tconst [selected, setSelected] = useState<\"positive\" | \"negative\" | null>(null);\n\tconst [comment, setComment] = useState(\"\");\n\tconst [submitted, setSubmitted] = useState(false);\n\n\tif (submitted) {\n\t\treturn (\n\t\t\t<div className=\"bg-secondary/50 border-t px-4 py-3 text-center\">\n\t\t\t\t<p className=\"text-sm text-muted-foreground\">Thank you for your feedback!</p>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={onSkip}\n\t\t\t\t\tclassName=\"text-xs text-blue-600 hover:underline mt-1\"\n\t\t\t\t>\n\t\t\t\t\tBack to AI Assistant\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"bg-secondary/50 border-t px-4 py-3\">\n\t\t\t<p className=\"text-sm text-foreground/80 text-center mb-2\">How was your experience?</p>\n\t\t\t<div className=\"flex justify-center gap-4 mb-2\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={() => setSelected(\"positive\")}\n\t\t\t\t\tclassName={`p-2 rounded-full transition-colors ${\n\t\t\t\t\t\tselected === \"positive\" ? \"bg-green-100 text-green-600\" : \"hover:bg-muted text-muted-foreground\"\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t<ThumbsUp className=\"h-5 w-5\" />\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={() => setSelected(\"negative\")}\n\t\t\t\t\tclassName={`p-2 rounded-full transition-colors ${\n\t\t\t\t\t\tselected === \"negative\" ? \"bg-red-100 text-red-600\" : \"hover:bg-muted text-muted-foreground\"\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t<ThumbsDown className=\"h-5 w-5\" />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t{selected && (\n\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t<textarea\n\t\t\t\t\t\tvalue={comment}\n\t\t\t\t\t\tonChange={(e) => setComment(e.target.value)}\n\t\t\t\t\t\tplaceholder=\"Any additional feedback? (optional)\"\n\t\t\t\t\t\tclassName=\"w-full text-xs p-2 border rounded resize-none h-16\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"flex justify-center gap-2\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tonSubmit(selected, comment || undefined);\n\t\t\t\t\t\t\t\tsetSubmitted(true);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclassName=\"text-xs text-white px-3 py-1 rounded\"\n\t\t\t\t\t\t\tstyle={{ backgroundColor: \"var(--ac-primary)\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSubmit\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={onSkip}\n\t\t\t\t\t\t\tclassName=\"text-xs text-muted-foreground hover:underline px-3 py-1\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSkip\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!selected && (\n\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onSkip}\n\t\t\t\t\t\tclassName=\"text-xs text-muted-foreground hover:underline\"\n\t\t\t\t\t>\n\t\t\t\t\t\tSkip\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"]}
|
package/dist/core.cjs
CHANGED
|
@@ -3,86 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
var chunkKBGPBUTI_cjs = require('./chunk-KBGPBUTI.cjs');
|
|
5
5
|
var chunkNG7OTWXQ_cjs = require('./chunk-NG7OTWXQ.cjs');
|
|
6
|
+
var chunkVYBHYFG3_cjs = require('./chunk-VYBHYFG3.cjs');
|
|
6
7
|
var chunkJOO6C3XT_cjs = require('./chunk-JOO6C3XT.cjs');
|
|
7
8
|
var chunk525KS5HM_cjs = require('./chunk-525KS5HM.cjs');
|
|
8
9
|
|
|
9
|
-
// src/core/message-store.ts
|
|
10
|
-
var STORAGE_PREFIX = "chat-messages-";
|
|
11
|
-
var MAX_SIZE_BYTES = 200 * 1024;
|
|
12
|
-
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
13
|
-
function getKey(projectId, sessionId) {
|
|
14
|
-
return `${STORAGE_PREFIX}${projectId}-${sessionId}`;
|
|
15
|
-
}
|
|
16
|
-
function loadMessages(projectId, sessionId) {
|
|
17
|
-
if (typeof window === "undefined") return [];
|
|
18
|
-
try {
|
|
19
|
-
const raw = localStorage.getItem(getKey(projectId, sessionId));
|
|
20
|
-
if (!raw) return [];
|
|
21
|
-
const data = JSON.parse(raw);
|
|
22
|
-
if (Date.now() - data.timestamp > MAX_AGE_MS) {
|
|
23
|
-
localStorage.removeItem(getKey(projectId, sessionId));
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
return data.messages || [];
|
|
27
|
-
} catch {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function saveMessages(projectId, sessionId, messages) {
|
|
32
|
-
if (typeof window === "undefined") return;
|
|
33
|
-
try {
|
|
34
|
-
let toStore = messages;
|
|
35
|
-
const data = { messages: toStore, timestamp: Date.now() };
|
|
36
|
-
let serialized = JSON.stringify(data);
|
|
37
|
-
if (serialized.length > MAX_SIZE_BYTES && toStore.length > 20) {
|
|
38
|
-
toStore = toStore.slice(-20);
|
|
39
|
-
data.messages = toStore;
|
|
40
|
-
serialized = JSON.stringify(data);
|
|
41
|
-
}
|
|
42
|
-
localStorage.setItem(getKey(projectId, sessionId), serialized);
|
|
43
|
-
} catch {
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function clearMessages(projectId, sessionId) {
|
|
47
|
-
if (typeof window === "undefined") return;
|
|
48
|
-
try {
|
|
49
|
-
localStorage.removeItem(getKey(projectId, sessionId));
|
|
50
|
-
} catch {
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function pruneExpiredMessages() {
|
|
54
|
-
if (typeof window === "undefined") return;
|
|
55
|
-
try {
|
|
56
|
-
const keysToRemove = [];
|
|
57
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
58
|
-
const key = localStorage.key(i);
|
|
59
|
-
if (!key?.startsWith(STORAGE_PREFIX)) continue;
|
|
60
|
-
try {
|
|
61
|
-
const raw = localStorage.getItem(key);
|
|
62
|
-
if (!raw) continue;
|
|
63
|
-
const data = JSON.parse(raw);
|
|
64
|
-
if (Date.now() - data.timestamp > MAX_AGE_MS) {
|
|
65
|
-
keysToRemove.push(key);
|
|
66
|
-
}
|
|
67
|
-
} catch {
|
|
68
|
-
keysToRemove.push(key);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
for (const key of keysToRemove) {
|
|
72
|
-
localStorage.removeItem(key);
|
|
73
|
-
}
|
|
74
|
-
} catch {
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
var saveTimeout = null;
|
|
78
|
-
function debouncedSaveMessages(projectId, sessionId, messages, delay = 500) {
|
|
79
|
-
if (typeof window === "undefined") return;
|
|
80
|
-
if (saveTimeout) clearTimeout(saveTimeout);
|
|
81
|
-
saveTimeout = setTimeout(() => {
|
|
82
|
-
saveMessages(projectId, sessionId, messages);
|
|
83
|
-
}, delay);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
10
|
// src/core/transport.ts
|
|
87
11
|
function minifyToolOutput(output) {
|
|
88
12
|
if (!output || typeof output !== "object") return output;
|
|
@@ -250,6 +174,26 @@ Object.defineProperty(exports, "LiveChatTransport", {
|
|
|
250
174
|
enumerable: true,
|
|
251
175
|
get: function () { return chunkNG7OTWXQ_cjs.LiveChatTransport; }
|
|
252
176
|
});
|
|
177
|
+
Object.defineProperty(exports, "clearMessages", {
|
|
178
|
+
enumerable: true,
|
|
179
|
+
get: function () { return chunkVYBHYFG3_cjs.clearMessages; }
|
|
180
|
+
});
|
|
181
|
+
Object.defineProperty(exports, "debouncedSaveMessages", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
get: function () { return chunkVYBHYFG3_cjs.debouncedSaveMessages; }
|
|
184
|
+
});
|
|
185
|
+
Object.defineProperty(exports, "loadMessages", {
|
|
186
|
+
enumerable: true,
|
|
187
|
+
get: function () { return chunkVYBHYFG3_cjs.loadMessages; }
|
|
188
|
+
});
|
|
189
|
+
Object.defineProperty(exports, "pruneExpiredMessages", {
|
|
190
|
+
enumerable: true,
|
|
191
|
+
get: function () { return chunkVYBHYFG3_cjs.pruneExpiredMessages; }
|
|
192
|
+
});
|
|
193
|
+
Object.defineProperty(exports, "saveMessages", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
get: function () { return chunkVYBHYFG3_cjs.saveMessages; }
|
|
196
|
+
});
|
|
253
197
|
Object.defineProperty(exports, "processImagesInHtml", {
|
|
254
198
|
enumerable: true,
|
|
255
199
|
get: function () { return chunkJOO6C3XT_cjs.processImagesInHtml; }
|
|
@@ -269,15 +213,10 @@ Object.defineProperty(exports, "isSsr", {
|
|
|
269
213
|
exports.INTERNAL_MESSAGE_PREFIX = INTERNAL_MESSAGE_PREFIX;
|
|
270
214
|
exports.USER_TYPES = USER_TYPES;
|
|
271
215
|
exports.USER_TYPE_LABEL_MAP = USER_TYPE_LABEL_MAP;
|
|
272
|
-
exports.clearMessages = clearMessages;
|
|
273
216
|
exports.createChatTransport = createChatTransport;
|
|
274
217
|
exports.createChatTransportSync = createChatTransportSync;
|
|
275
|
-
exports.debouncedSaveMessages = debouncedSaveMessages;
|
|
276
218
|
exports.isInternalMessage = isInternalMessage;
|
|
277
|
-
exports.loadMessages = loadMessages;
|
|
278
219
|
exports.minifyToolOutput = minifyToolOutput;
|
|
279
220
|
exports.prepareMessages = prepareMessages;
|
|
280
|
-
exports.pruneExpiredMessages = pruneExpiredMessages;
|
|
281
|
-
exports.saveMessages = saveMessages;
|
|
282
221
|
//# sourceMappingURL=core.cjs.map
|
|
283
222
|
//# sourceMappingURL=core.cjs.map
|
package/dist/core.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/message-store.ts","../src/core/transport.ts","../src/core/constants/user-types.ts"],"names":[],"mappings":"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","file":"core.cjs","sourcesContent":["\"use client\";\n\n/**\n * Cross-page message persistence via `localStorage`.\n *\n * Preserves conversation UI across full page navigations without\n * re-POSTing to the backend.\n *\n * All storage access is guarded against SSR — every function is a safe\n * no-op when `window` / `localStorage` is unavailable.\n */\n\nconst STORAGE_PREFIX = \"chat-messages-\";\n\n/** Maximum payload size per session (200 KB). */\nconst MAX_SIZE_BYTES = 200 * 1024;\n\n/** Messages expire after 24 hours of inactivity. */\nconst MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** Shape of a single persisted message. */\nexport interface StoredMessage {\n /** Message identifier */\n id: string;\n /** Role: user / assistant / system */\n role: string;\n /** Structured parts array (text, tool calls, etc.) */\n parts: unknown[];\n /** ISO-8601 creation timestamp */\n createdAt?: string;\n}\n\n/** Internal wrapper stored in localStorage. */\ninterface StoredData {\n messages: StoredMessage[];\n timestamp: number;\n}\n\n/**\n * Build the localStorage key for a given project + session pair.\n *\n * @internal\n */\nfunction getKey(projectId: string, sessionId: string): string {\n return `${STORAGE_PREFIX}${projectId}-${sessionId}`;\n}\n\n/**\n * Load persisted messages for a session.\n *\n * Returns an empty array when nothing is stored, the data is expired\n * or corrupted, or when running on the server.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n */\nexport function loadMessages(projectId: string, sessionId: string): StoredMessage[] {\n if (typeof window === \"undefined\") return [];\n\n try {\n const raw = localStorage.getItem(getKey(projectId, sessionId));\n if (!raw) return [];\n\n const data: StoredData = JSON.parse(raw);\n\n // Check expiry\n if (Date.now() - data.timestamp > MAX_AGE_MS) {\n localStorage.removeItem(getKey(projectId, sessionId));\n return [];\n }\n\n return data.messages || [];\n } catch {\n return [];\n }\n}\n\n/**\n * Save messages to localStorage.\n *\n * Trims to the last 20 messages if the serialized payload exceeds\n * `MAX_SIZE_BYTES`.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n * @param messages - Messages to persist\n */\nexport function saveMessages(\n projectId: string,\n sessionId: string,\n messages: StoredMessage[],\n): void {\n if (typeof window === \"undefined\") return;\n\n try {\n let toStore = messages;\n const data: StoredData = { messages: toStore, timestamp: Date.now() };\n let serialized = JSON.stringify(data);\n\n if (serialized.length > MAX_SIZE_BYTES && toStore.length > 20) {\n toStore = toStore.slice(-20);\n data.messages = toStore;\n serialized = JSON.stringify(data);\n }\n\n localStorage.setItem(getKey(projectId, sessionId), serialized);\n } catch {\n // localStorage full or unavailable — silently ignore\n }\n}\n\n/**\n * Clear stored messages for a session.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n */\nexport function clearMessages(projectId: string, sessionId: string): void {\n if (typeof window === \"undefined\") return;\n\n try {\n localStorage.removeItem(getKey(projectId, sessionId));\n } catch {\n // ignore\n }\n}\n\n/**\n * Prune all expired message entries from localStorage.\n *\n * Call once on widget / provider initialisation to prevent stale data\n * from accumulating.\n */\nexport function pruneExpiredMessages(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n const keysToRemove: string[] = [];\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (!key?.startsWith(STORAGE_PREFIX)) continue;\n\n try {\n const raw = localStorage.getItem(key);\n if (!raw) continue;\n const data: StoredData = JSON.parse(raw);\n if (Date.now() - data.timestamp > MAX_AGE_MS) {\n keysToRemove.push(key);\n }\n } catch {\n keysToRemove.push(key!);\n }\n }\n\n for (const key of keysToRemove) {\n localStorage.removeItem(key);\n }\n } catch {\n // ignore\n }\n}\n\n/** Handle for the debounce timer. */\nlet saveTimeout: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * Debounced save — call on every `messages` change.\n *\n * Coalesces rapid updates (e.g. during streaming) into a single write.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n * @param messages - Current messages array\n * @param delay - Debounce delay in ms (default `500`)\n */\nexport function debouncedSaveMessages(\n projectId: string,\n sessionId: string,\n messages: StoredMessage[],\n delay = 500,\n): void {\n if (typeof window === \"undefined\") return;\n\n if (saveTimeout) clearTimeout(saveTimeout);\n saveTimeout = setTimeout(() => {\n saveMessages(projectId, sessionId, messages);\n }, delay);\n}\n","\"use client\";\n\nimport type { ChatConfig } from \"./types\";\n\n/**\n * Options for creating a chat transport instance.\n */\nexport interface CreateChatTransportOptions {\n /** Maximum number of messages to include in a single request (default `20`) */\n maxMessages?: number;\n /** Current session identifier */\n sessionId?: string;\n /** Pre-set user type / persona key */\n userType?: string;\n /** Current page URL (for contextual answers) */\n pageUrl?: string;\n /** Current page title */\n pageTitle?: string;\n /** Signed WP user identity token */\n wpUserToken?: string;\n /**\n * Mutable ref-like getter for the analytics message ID.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getAnalyticsMessageId?: () => string | null;\n /**\n * Mutable ref-like getter for the current user type.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getUserType?: () => string | null;\n /**\n * Mutable ref-like getter for the current session ID.\n * Called inside `prepareSendMessagesRequest` in case it changes at runtime.\n */\n getSessionId?: () => string;\n}\n\n/**\n * Minify a tool output before sending it back to the LLM.\n *\n * Display tools use `_displayData` for the UI — the LLM only needs the\n * summary / context portion. Large outputs are truncated.\n *\n * @internal\n */\nexport function minifyToolOutput(output: unknown): unknown {\n if (!output || typeof output !== \"object\") return output;\n const obj = output as Record<string, unknown>;\n\n // 1. Display-only tools: strip _displayData, keep message/summary\n if (\"_displayData\" in obj) {\n const { _displayData: _, ...contextData } = obj;\n return contextData;\n }\n\n // 2. searchKnowledgeBase: LLM already used results, no need to resend\n if (\"sources\" in obj && Array.isArray(obj.sources)) {\n return { _searched: true, totalResults: obj.totalResults };\n }\n\n // 3. Fallback: truncate any large outputs (>1.5 KB)\n const outputStr = JSON.stringify(obj);\n if (outputStr.length > 1500) {\n const summary: Record<string, unknown> = { _truncated: true };\n if (Array.isArray(obj)) {\n summary.itemCount = obj.length;\n } else {\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\" && v.length < 100) summary[k] = v;\n else if (typeof v === \"number\" || typeof v === \"boolean\") summary[k] = v;\n }\n }\n return summary;\n }\n\n return output;\n}\n\n/**\n * Prune and minify a messages array for sending to the API.\n *\n * 1. Keeps the first message (system / context) and the last `maxMessages - 1`.\n * 2. Deep-clones messages so the local UI state is not mutated.\n * 3. Strips large tool outputs via `minifyToolOutput`.\n *\n * @internal\n */\nexport function prepareMessages(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: any[],\n maxMessages: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any[] {\n let pruned = messages;\n\n if (messages.length > maxMessages) {\n pruned = [messages[0], ...messages.slice(-(maxMessages - 1))];\n }\n\n // Deep clone and minify tool outputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cloned = JSON.parse(JSON.stringify(pruned)) as any[];\n for (const msg of cloned) {\n if (msg.role === \"assistant\" && msg.parts) {\n for (const part of msg.parts) {\n if (part.type?.startsWith(\"tool-\") && part.output !== undefined) {\n part.output = minifyToolOutput(part.output);\n }\n }\n }\n }\n\n return cloned;\n}\n\n/**\n * Create a configured `DefaultChatTransport` instance from the AI SDK.\n *\n * The transport handles authentication, message pruning, tool-output\n * minification, and attaches project / session metadata to every request.\n *\n * Uses a dynamic `import(\"ai\")` so that `ai` stays an optional peer\n * dependency — the import is only resolved at call time.\n *\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A `DefaultChatTransport` instance ready for `useChat()`\n *\n * @example\n * ```ts\n * const transport = await createChatTransport(\n * { projectId: \"abc\", apiEndpoint: \"https://api.example.com\", apiKey: \"key\" },\n * { maxMessages: 20, getSessionId: () => sessionIdRef.current },\n * );\n * const { messages } = useChat({ transport });\n * ```\n */\nexport async function createChatTransport(\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const { DefaultChatTransport } = await import(\"ai\");\n\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n prepareSendMessagesRequest: ({ id, messages, trigger }) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n\n/**\n * Synchronous variant of `createChatTransport` for use when `ai`\n * is already bundled (i.e. not dynamically imported).\n *\n * Requires the caller to pass in the `DefaultChatTransport` constructor.\n *\n * @param DefaultChatTransport - The `DefaultChatTransport` class from `\"ai\"`\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A configured `DefaultChatTransport` instance\n */\nexport function createChatTransportSync(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n DefaultChatTransport: any,\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prepareSendMessagesRequest: ({ id, messages, trigger }: any) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n","\"use client\";\n\n/**\n * User type constants and helpers.\n *\n * Defines the available visitor personas that the `AgentDetection` tool\n * can assign. These are generic defaults — consumers can extend them via\n * configuration.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A visitor persona / user type definition.\n */\nexport interface UserType {\n /** Machine-readable identifier (e.g. `\"Guest\"`) */\n id: string;\n /** Human-readable label */\n label: string;\n /** Short description of this persona */\n description: string;\n /**\n * Icon identifier.\n *\n * In the SDK this is a string key (e.g. `\"User\"`, `\"Shield\"`, `\"Zap\"`)\n * rather than a Lucide component to avoid coupling core logic to a\n * specific icon library.\n */\n icon: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Default user types available for the `AgentDetection` tool.\n */\nexport const USER_TYPES: UserType[] = [\n {\n id: \"Guest\",\n label: \"Guest\",\n description: \"Just browsing\",\n icon: \"User\",\n },\n {\n id: \"Customer\",\n label: \"Customer\",\n description: \"Existing customer with questions\",\n icon: \"Shield\",\n },\n {\n id: \"Partner\",\n label: \"Partner\",\n description: \"Business partner or professional\",\n icon: \"Zap\",\n },\n];\n\n/**\n * Map from display label to user-type ID.\n *\n * Used to normalise user-type strings that come from the AI\n * (which may use the label rather than the ID).\n */\nexport const USER_TYPE_LABEL_MAP: Record<string, string> = {\n Guest: \"Guest\",\n Customer: \"Customer\",\n Partner: \"Partner\",\n};\n\n/**\n * Prefix for internal / hidden messages.\n *\n * Messages starting with this string are never rendered in the UI.\n */\nexport const INTERNAL_MESSAGE_PREFIX = \"[internal]\";\n\n/**\n * Check whether a message should be hidden from the UI.\n *\n * @param text - The raw message text\n * @returns `true` if the message is internal\n */\nexport function isInternalMessage(text: string): boolean {\n return text.startsWith(INTERNAL_MESSAGE_PREFIX);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/transport.ts","../src/core/constants/user-types.ts"],"names":[],"mappings":"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","file":"core.cjs","sourcesContent":["\"use client\";\n\nimport type { ChatConfig } from \"./types\";\n\n/**\n * Options for creating a chat transport instance.\n */\nexport interface CreateChatTransportOptions {\n /** Maximum number of messages to include in a single request (default `20`) */\n maxMessages?: number;\n /** Current session identifier */\n sessionId?: string;\n /** Pre-set user type / persona key */\n userType?: string;\n /** Current page URL (for contextual answers) */\n pageUrl?: string;\n /** Current page title */\n pageTitle?: string;\n /** Signed WP user identity token */\n wpUserToken?: string;\n /**\n * Mutable ref-like getter for the analytics message ID.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getAnalyticsMessageId?: () => string | null;\n /**\n * Mutable ref-like getter for the current user type.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getUserType?: () => string | null;\n /**\n * Mutable ref-like getter for the current session ID.\n * Called inside `prepareSendMessagesRequest` in case it changes at runtime.\n */\n getSessionId?: () => string;\n}\n\n/**\n * Minify a tool output before sending it back to the LLM.\n *\n * Display tools use `_displayData` for the UI — the LLM only needs the\n * summary / context portion. Large outputs are truncated.\n *\n * @internal\n */\nexport function minifyToolOutput(output: unknown): unknown {\n if (!output || typeof output !== \"object\") return output;\n const obj = output as Record<string, unknown>;\n\n // 1. Display-only tools: strip _displayData, keep message/summary\n if (\"_displayData\" in obj) {\n const { _displayData: _, ...contextData } = obj;\n return contextData;\n }\n\n // 2. searchKnowledgeBase: LLM already used results, no need to resend\n if (\"sources\" in obj && Array.isArray(obj.sources)) {\n return { _searched: true, totalResults: obj.totalResults };\n }\n\n // 3. Fallback: truncate any large outputs (>1.5 KB)\n const outputStr = JSON.stringify(obj);\n if (outputStr.length > 1500) {\n const summary: Record<string, unknown> = { _truncated: true };\n if (Array.isArray(obj)) {\n summary.itemCount = obj.length;\n } else {\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\" && v.length < 100) summary[k] = v;\n else if (typeof v === \"number\" || typeof v === \"boolean\") summary[k] = v;\n }\n }\n return summary;\n }\n\n return output;\n}\n\n/**\n * Prune and minify a messages array for sending to the API.\n *\n * 1. Keeps the first message (system / context) and the last `maxMessages - 1`.\n * 2. Deep-clones messages so the local UI state is not mutated.\n * 3. Strips large tool outputs via `minifyToolOutput`.\n *\n * @internal\n */\nexport function prepareMessages(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: any[],\n maxMessages: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any[] {\n let pruned = messages;\n\n if (messages.length > maxMessages) {\n pruned = [messages[0], ...messages.slice(-(maxMessages - 1))];\n }\n\n // Deep clone and minify tool outputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cloned = JSON.parse(JSON.stringify(pruned)) as any[];\n for (const msg of cloned) {\n if (msg.role === \"assistant\" && msg.parts) {\n for (const part of msg.parts) {\n if (part.type?.startsWith(\"tool-\") && part.output !== undefined) {\n part.output = minifyToolOutput(part.output);\n }\n }\n }\n }\n\n return cloned;\n}\n\n/**\n * Create a configured `DefaultChatTransport` instance from the AI SDK.\n *\n * The transport handles authentication, message pruning, tool-output\n * minification, and attaches project / session metadata to every request.\n *\n * Uses a dynamic `import(\"ai\")` so that `ai` stays an optional peer\n * dependency — the import is only resolved at call time.\n *\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A `DefaultChatTransport` instance ready for `useChat()`\n *\n * @example\n * ```ts\n * const transport = await createChatTransport(\n * { projectId: \"abc\", apiEndpoint: \"https://api.example.com\", apiKey: \"key\" },\n * { maxMessages: 20, getSessionId: () => sessionIdRef.current },\n * );\n * const { messages } = useChat({ transport });\n * ```\n */\nexport async function createChatTransport(\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const { DefaultChatTransport } = await import(\"ai\");\n\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n prepareSendMessagesRequest: ({ id, messages, trigger }) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n\n/**\n * Synchronous variant of `createChatTransport` for use when `ai`\n * is already bundled (i.e. not dynamically imported).\n *\n * Requires the caller to pass in the `DefaultChatTransport` constructor.\n *\n * @param DefaultChatTransport - The `DefaultChatTransport` class from `\"ai\"`\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A configured `DefaultChatTransport` instance\n */\nexport function createChatTransportSync(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n DefaultChatTransport: any,\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prepareSendMessagesRequest: ({ id, messages, trigger }: any) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n","\"use client\";\n\n/**\n * User type constants and helpers.\n *\n * Defines the available visitor personas that the `AgentDetection` tool\n * can assign. These are generic defaults — consumers can extend them via\n * configuration.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A visitor persona / user type definition.\n */\nexport interface UserType {\n /** Machine-readable identifier (e.g. `\"Guest\"`) */\n id: string;\n /** Human-readable label */\n label: string;\n /** Short description of this persona */\n description: string;\n /**\n * Icon identifier.\n *\n * In the SDK this is a string key (e.g. `\"User\"`, `\"Shield\"`, `\"Zap\"`)\n * rather than a Lucide component to avoid coupling core logic to a\n * specific icon library.\n */\n icon: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Default user types available for the `AgentDetection` tool.\n */\nexport const USER_TYPES: UserType[] = [\n {\n id: \"Guest\",\n label: \"Guest\",\n description: \"Just browsing\",\n icon: \"User\",\n },\n {\n id: \"Customer\",\n label: \"Customer\",\n description: \"Existing customer with questions\",\n icon: \"Shield\",\n },\n {\n id: \"Partner\",\n label: \"Partner\",\n description: \"Business partner or professional\",\n icon: \"Zap\",\n },\n];\n\n/**\n * Map from display label to user-type ID.\n *\n * Used to normalise user-type strings that come from the AI\n * (which may use the label rather than the ID).\n */\nexport const USER_TYPE_LABEL_MAP: Record<string, string> = {\n Guest: \"Guest\",\n Customer: \"Customer\",\n Partner: \"Partner\",\n};\n\n/**\n * Prefix for internal / hidden messages.\n *\n * Messages starting with this string are never rendered in the UI.\n */\nexport const INTERNAL_MESSAGE_PREFIX = \"[internal]\";\n\n/**\n * Check whether a message should be hidden from the UI.\n *\n * @param text - The raw message text\n * @returns `true` if the message is internal\n */\nexport function isInternalMessage(text: string): boolean {\n return text.startsWith(INTERNAL_MESSAGE_PREFIX);\n}\n"]}
|
package/dist/core.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { d as ChatConfig } from './types-DRa1zFlN.cjs';
|
|
2
|
+
export { c as ChatAttachmentInput, e as ChatEventCallbacks, f as ChatMessage, b as ChatProviderProps, C as ComponentAction, L as Language, g as LiveChatMessage, h as LiveChatState, Q as QuestionConfig, S as SlotMap, j as SlotProps, i as ThemeConfig, T as ToolRendererProps, a as ToolResult } from './types-DRa1zFlN.cjs';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
import * as ai from 'ai';
|
|
5
5
|
export { I as InteractionMetadata, a as InteractionType, T as TrackInteractionParams, U as UseInteractionTrackerOptions, g as generateSessionId, u as useInteractionTracker } from './interaction-tracker-D9P1Oq4j.cjs';
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { d as ChatConfig } from './types-DRa1zFlN.js';
|
|
2
|
+
export { c as ChatAttachmentInput, e as ChatEventCallbacks, f as ChatMessage, b as ChatProviderProps, C as ComponentAction, L as Language, g as LiveChatMessage, h as LiveChatState, Q as QuestionConfig, S as SlotMap, j as SlotProps, i as ThemeConfig, T as ToolRendererProps, a as ToolResult } from './types-DRa1zFlN.js';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
import * as ai from 'ai';
|
|
5
5
|
export { I as InteractionMetadata, a as InteractionType, T as TrackInteractionParams, U as UseInteractionTrackerOptions, g as generateSessionId, u as useInteractionTracker } from './interaction-tracker-D9P1Oq4j.js';
|
package/dist/core.js
CHANGED
|
@@ -1,86 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
export { generateSessionId, useInteractionTracker } from './chunk-MT2AMINB.js';
|
|
3
3
|
export { LiveChatTransport } from './chunk-BKDV2H6Z.js';
|
|
4
|
+
export { clearMessages, debouncedSaveMessages, loadMessages, pruneExpiredMessages, saveMessages } from './chunk-CNPYBLLT.js';
|
|
4
5
|
export { processImagesInHtml } from './chunk-PS3U7T37.js';
|
|
5
6
|
export { addUtmParams, cn, isSsr } from './chunk-3RW7O444.js';
|
|
6
7
|
|
|
7
|
-
// src/core/message-store.ts
|
|
8
|
-
var STORAGE_PREFIX = "chat-messages-";
|
|
9
|
-
var MAX_SIZE_BYTES = 200 * 1024;
|
|
10
|
-
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
11
|
-
function getKey(projectId, sessionId) {
|
|
12
|
-
return `${STORAGE_PREFIX}${projectId}-${sessionId}`;
|
|
13
|
-
}
|
|
14
|
-
function loadMessages(projectId, sessionId) {
|
|
15
|
-
if (typeof window === "undefined") return [];
|
|
16
|
-
try {
|
|
17
|
-
const raw = localStorage.getItem(getKey(projectId, sessionId));
|
|
18
|
-
if (!raw) return [];
|
|
19
|
-
const data = JSON.parse(raw);
|
|
20
|
-
if (Date.now() - data.timestamp > MAX_AGE_MS) {
|
|
21
|
-
localStorage.removeItem(getKey(projectId, sessionId));
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
return data.messages || [];
|
|
25
|
-
} catch {
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function saveMessages(projectId, sessionId, messages) {
|
|
30
|
-
if (typeof window === "undefined") return;
|
|
31
|
-
try {
|
|
32
|
-
let toStore = messages;
|
|
33
|
-
const data = { messages: toStore, timestamp: Date.now() };
|
|
34
|
-
let serialized = JSON.stringify(data);
|
|
35
|
-
if (serialized.length > MAX_SIZE_BYTES && toStore.length > 20) {
|
|
36
|
-
toStore = toStore.slice(-20);
|
|
37
|
-
data.messages = toStore;
|
|
38
|
-
serialized = JSON.stringify(data);
|
|
39
|
-
}
|
|
40
|
-
localStorage.setItem(getKey(projectId, sessionId), serialized);
|
|
41
|
-
} catch {
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function clearMessages(projectId, sessionId) {
|
|
45
|
-
if (typeof window === "undefined") return;
|
|
46
|
-
try {
|
|
47
|
-
localStorage.removeItem(getKey(projectId, sessionId));
|
|
48
|
-
} catch {
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function pruneExpiredMessages() {
|
|
52
|
-
if (typeof window === "undefined") return;
|
|
53
|
-
try {
|
|
54
|
-
const keysToRemove = [];
|
|
55
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
56
|
-
const key = localStorage.key(i);
|
|
57
|
-
if (!key?.startsWith(STORAGE_PREFIX)) continue;
|
|
58
|
-
try {
|
|
59
|
-
const raw = localStorage.getItem(key);
|
|
60
|
-
if (!raw) continue;
|
|
61
|
-
const data = JSON.parse(raw);
|
|
62
|
-
if (Date.now() - data.timestamp > MAX_AGE_MS) {
|
|
63
|
-
keysToRemove.push(key);
|
|
64
|
-
}
|
|
65
|
-
} catch {
|
|
66
|
-
keysToRemove.push(key);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
for (const key of keysToRemove) {
|
|
70
|
-
localStorage.removeItem(key);
|
|
71
|
-
}
|
|
72
|
-
} catch {
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
var saveTimeout = null;
|
|
76
|
-
function debouncedSaveMessages(projectId, sessionId, messages, delay = 500) {
|
|
77
|
-
if (typeof window === "undefined") return;
|
|
78
|
-
if (saveTimeout) clearTimeout(saveTimeout);
|
|
79
|
-
saveTimeout = setTimeout(() => {
|
|
80
|
-
saveMessages(projectId, sessionId, messages);
|
|
81
|
-
}, delay);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
8
|
// src/core/transport.ts
|
|
85
9
|
function minifyToolOutput(output) {
|
|
86
10
|
if (!output || typeof output !== "object") return output;
|
|
@@ -236,6 +160,6 @@ function isInternalMessage(text) {
|
|
|
236
160
|
return text.startsWith(INTERNAL_MESSAGE_PREFIX);
|
|
237
161
|
}
|
|
238
162
|
|
|
239
|
-
export { INTERNAL_MESSAGE_PREFIX, USER_TYPES, USER_TYPE_LABEL_MAP,
|
|
163
|
+
export { INTERNAL_MESSAGE_PREFIX, USER_TYPES, USER_TYPE_LABEL_MAP, createChatTransport, createChatTransportSync, isInternalMessage, minifyToolOutput, prepareMessages };
|
|
240
164
|
//# sourceMappingURL=core.js.map
|
|
241
165
|
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/message-store.ts","../src/core/transport.ts","../src/core/constants/user-types.ts"],"names":[],"mappings":"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","file":"core.js","sourcesContent":["\"use client\";\n\n/**\n * Cross-page message persistence via `localStorage`.\n *\n * Preserves conversation UI across full page navigations without\n * re-POSTing to the backend.\n *\n * All storage access is guarded against SSR — every function is a safe\n * no-op when `window` / `localStorage` is unavailable.\n */\n\nconst STORAGE_PREFIX = \"chat-messages-\";\n\n/** Maximum payload size per session (200 KB). */\nconst MAX_SIZE_BYTES = 200 * 1024;\n\n/** Messages expire after 24 hours of inactivity. */\nconst MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** Shape of a single persisted message. */\nexport interface StoredMessage {\n /** Message identifier */\n id: string;\n /** Role: user / assistant / system */\n role: string;\n /** Structured parts array (text, tool calls, etc.) */\n parts: unknown[];\n /** ISO-8601 creation timestamp */\n createdAt?: string;\n}\n\n/** Internal wrapper stored in localStorage. */\ninterface StoredData {\n messages: StoredMessage[];\n timestamp: number;\n}\n\n/**\n * Build the localStorage key for a given project + session pair.\n *\n * @internal\n */\nfunction getKey(projectId: string, sessionId: string): string {\n return `${STORAGE_PREFIX}${projectId}-${sessionId}`;\n}\n\n/**\n * Load persisted messages for a session.\n *\n * Returns an empty array when nothing is stored, the data is expired\n * or corrupted, or when running on the server.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n */\nexport function loadMessages(projectId: string, sessionId: string): StoredMessage[] {\n if (typeof window === \"undefined\") return [];\n\n try {\n const raw = localStorage.getItem(getKey(projectId, sessionId));\n if (!raw) return [];\n\n const data: StoredData = JSON.parse(raw);\n\n // Check expiry\n if (Date.now() - data.timestamp > MAX_AGE_MS) {\n localStorage.removeItem(getKey(projectId, sessionId));\n return [];\n }\n\n return data.messages || [];\n } catch {\n return [];\n }\n}\n\n/**\n * Save messages to localStorage.\n *\n * Trims to the last 20 messages if the serialized payload exceeds\n * `MAX_SIZE_BYTES`.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n * @param messages - Messages to persist\n */\nexport function saveMessages(\n projectId: string,\n sessionId: string,\n messages: StoredMessage[],\n): void {\n if (typeof window === \"undefined\") return;\n\n try {\n let toStore = messages;\n const data: StoredData = { messages: toStore, timestamp: Date.now() };\n let serialized = JSON.stringify(data);\n\n if (serialized.length > MAX_SIZE_BYTES && toStore.length > 20) {\n toStore = toStore.slice(-20);\n data.messages = toStore;\n serialized = JSON.stringify(data);\n }\n\n localStorage.setItem(getKey(projectId, sessionId), serialized);\n } catch {\n // localStorage full or unavailable — silently ignore\n }\n}\n\n/**\n * Clear stored messages for a session.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n */\nexport function clearMessages(projectId: string, sessionId: string): void {\n if (typeof window === \"undefined\") return;\n\n try {\n localStorage.removeItem(getKey(projectId, sessionId));\n } catch {\n // ignore\n }\n}\n\n/**\n * Prune all expired message entries from localStorage.\n *\n * Call once on widget / provider initialisation to prevent stale data\n * from accumulating.\n */\nexport function pruneExpiredMessages(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n const keysToRemove: string[] = [];\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (!key?.startsWith(STORAGE_PREFIX)) continue;\n\n try {\n const raw = localStorage.getItem(key);\n if (!raw) continue;\n const data: StoredData = JSON.parse(raw);\n if (Date.now() - data.timestamp > MAX_AGE_MS) {\n keysToRemove.push(key);\n }\n } catch {\n keysToRemove.push(key!);\n }\n }\n\n for (const key of keysToRemove) {\n localStorage.removeItem(key);\n }\n } catch {\n // ignore\n }\n}\n\n/** Handle for the debounce timer. */\nlet saveTimeout: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * Debounced save — call on every `messages` change.\n *\n * Coalesces rapid updates (e.g. during streaming) into a single write.\n *\n * @param projectId - Aigentyc project ID\n * @param sessionId - Current chat session ID\n * @param messages - Current messages array\n * @param delay - Debounce delay in ms (default `500`)\n */\nexport function debouncedSaveMessages(\n projectId: string,\n sessionId: string,\n messages: StoredMessage[],\n delay = 500,\n): void {\n if (typeof window === \"undefined\") return;\n\n if (saveTimeout) clearTimeout(saveTimeout);\n saveTimeout = setTimeout(() => {\n saveMessages(projectId, sessionId, messages);\n }, delay);\n}\n","\"use client\";\n\nimport type { ChatConfig } from \"./types\";\n\n/**\n * Options for creating a chat transport instance.\n */\nexport interface CreateChatTransportOptions {\n /** Maximum number of messages to include in a single request (default `20`) */\n maxMessages?: number;\n /** Current session identifier */\n sessionId?: string;\n /** Pre-set user type / persona key */\n userType?: string;\n /** Current page URL (for contextual answers) */\n pageUrl?: string;\n /** Current page title */\n pageTitle?: string;\n /** Signed WP user identity token */\n wpUserToken?: string;\n /**\n * Mutable ref-like getter for the analytics message ID.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getAnalyticsMessageId?: () => string | null;\n /**\n * Mutable ref-like getter for the current user type.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getUserType?: () => string | null;\n /**\n * Mutable ref-like getter for the current session ID.\n * Called inside `prepareSendMessagesRequest` in case it changes at runtime.\n */\n getSessionId?: () => string;\n}\n\n/**\n * Minify a tool output before sending it back to the LLM.\n *\n * Display tools use `_displayData` for the UI — the LLM only needs the\n * summary / context portion. Large outputs are truncated.\n *\n * @internal\n */\nexport function minifyToolOutput(output: unknown): unknown {\n if (!output || typeof output !== \"object\") return output;\n const obj = output as Record<string, unknown>;\n\n // 1. Display-only tools: strip _displayData, keep message/summary\n if (\"_displayData\" in obj) {\n const { _displayData: _, ...contextData } = obj;\n return contextData;\n }\n\n // 2. searchKnowledgeBase: LLM already used results, no need to resend\n if (\"sources\" in obj && Array.isArray(obj.sources)) {\n return { _searched: true, totalResults: obj.totalResults };\n }\n\n // 3. Fallback: truncate any large outputs (>1.5 KB)\n const outputStr = JSON.stringify(obj);\n if (outputStr.length > 1500) {\n const summary: Record<string, unknown> = { _truncated: true };\n if (Array.isArray(obj)) {\n summary.itemCount = obj.length;\n } else {\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\" && v.length < 100) summary[k] = v;\n else if (typeof v === \"number\" || typeof v === \"boolean\") summary[k] = v;\n }\n }\n return summary;\n }\n\n return output;\n}\n\n/**\n * Prune and minify a messages array for sending to the API.\n *\n * 1. Keeps the first message (system / context) and the last `maxMessages - 1`.\n * 2. Deep-clones messages so the local UI state is not mutated.\n * 3. Strips large tool outputs via `minifyToolOutput`.\n *\n * @internal\n */\nexport function prepareMessages(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: any[],\n maxMessages: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any[] {\n let pruned = messages;\n\n if (messages.length > maxMessages) {\n pruned = [messages[0], ...messages.slice(-(maxMessages - 1))];\n }\n\n // Deep clone and minify tool outputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cloned = JSON.parse(JSON.stringify(pruned)) as any[];\n for (const msg of cloned) {\n if (msg.role === \"assistant\" && msg.parts) {\n for (const part of msg.parts) {\n if (part.type?.startsWith(\"tool-\") && part.output !== undefined) {\n part.output = minifyToolOutput(part.output);\n }\n }\n }\n }\n\n return cloned;\n}\n\n/**\n * Create a configured `DefaultChatTransport` instance from the AI SDK.\n *\n * The transport handles authentication, message pruning, tool-output\n * minification, and attaches project / session metadata to every request.\n *\n * Uses a dynamic `import(\"ai\")` so that `ai` stays an optional peer\n * dependency — the import is only resolved at call time.\n *\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A `DefaultChatTransport` instance ready for `useChat()`\n *\n * @example\n * ```ts\n * const transport = await createChatTransport(\n * { projectId: \"abc\", apiEndpoint: \"https://api.example.com\", apiKey: \"key\" },\n * { maxMessages: 20, getSessionId: () => sessionIdRef.current },\n * );\n * const { messages } = useChat({ transport });\n * ```\n */\nexport async function createChatTransport(\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const { DefaultChatTransport } = await import(\"ai\");\n\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n prepareSendMessagesRequest: ({ id, messages, trigger }) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n\n/**\n * Synchronous variant of `createChatTransport` for use when `ai`\n * is already bundled (i.e. not dynamically imported).\n *\n * Requires the caller to pass in the `DefaultChatTransport` constructor.\n *\n * @param DefaultChatTransport - The `DefaultChatTransport` class from `\"ai\"`\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A configured `DefaultChatTransport` instance\n */\nexport function createChatTransportSync(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n DefaultChatTransport: any,\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prepareSendMessagesRequest: ({ id, messages, trigger }: any) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n","\"use client\";\n\n/**\n * User type constants and helpers.\n *\n * Defines the available visitor personas that the `AgentDetection` tool\n * can assign. These are generic defaults — consumers can extend them via\n * configuration.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A visitor persona / user type definition.\n */\nexport interface UserType {\n /** Machine-readable identifier (e.g. `\"Guest\"`) */\n id: string;\n /** Human-readable label */\n label: string;\n /** Short description of this persona */\n description: string;\n /**\n * Icon identifier.\n *\n * In the SDK this is a string key (e.g. `\"User\"`, `\"Shield\"`, `\"Zap\"`)\n * rather than a Lucide component to avoid coupling core logic to a\n * specific icon library.\n */\n icon: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Default user types available for the `AgentDetection` tool.\n */\nexport const USER_TYPES: UserType[] = [\n {\n id: \"Guest\",\n label: \"Guest\",\n description: \"Just browsing\",\n icon: \"User\",\n },\n {\n id: \"Customer\",\n label: \"Customer\",\n description: \"Existing customer with questions\",\n icon: \"Shield\",\n },\n {\n id: \"Partner\",\n label: \"Partner\",\n description: \"Business partner or professional\",\n icon: \"Zap\",\n },\n];\n\n/**\n * Map from display label to user-type ID.\n *\n * Used to normalise user-type strings that come from the AI\n * (which may use the label rather than the ID).\n */\nexport const USER_TYPE_LABEL_MAP: Record<string, string> = {\n Guest: \"Guest\",\n Customer: \"Customer\",\n Partner: \"Partner\",\n};\n\n/**\n * Prefix for internal / hidden messages.\n *\n * Messages starting with this string are never rendered in the UI.\n */\nexport const INTERNAL_MESSAGE_PREFIX = \"[internal]\";\n\n/**\n * Check whether a message should be hidden from the UI.\n *\n * @param text - The raw message text\n * @returns `true` if the message is internal\n */\nexport function isInternalMessage(text: string): boolean {\n return text.startsWith(INTERNAL_MESSAGE_PREFIX);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/transport.ts","../src/core/constants/user-types.ts"],"names":[],"mappings":"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","file":"core.js","sourcesContent":["\"use client\";\n\nimport type { ChatConfig } from \"./types\";\n\n/**\n * Options for creating a chat transport instance.\n */\nexport interface CreateChatTransportOptions {\n /** Maximum number of messages to include in a single request (default `20`) */\n maxMessages?: number;\n /** Current session identifier */\n sessionId?: string;\n /** Pre-set user type / persona key */\n userType?: string;\n /** Current page URL (for contextual answers) */\n pageUrl?: string;\n /** Current page title */\n pageTitle?: string;\n /** Signed WP user identity token */\n wpUserToken?: string;\n /**\n * Mutable ref-like getter for the analytics message ID.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getAnalyticsMessageId?: () => string | null;\n /**\n * Mutable ref-like getter for the current user type.\n * Called inside `prepareSendMessagesRequest` to read the latest value.\n */\n getUserType?: () => string | null;\n /**\n * Mutable ref-like getter for the current session ID.\n * Called inside `prepareSendMessagesRequest` in case it changes at runtime.\n */\n getSessionId?: () => string;\n}\n\n/**\n * Minify a tool output before sending it back to the LLM.\n *\n * Display tools use `_displayData` for the UI — the LLM only needs the\n * summary / context portion. Large outputs are truncated.\n *\n * @internal\n */\nexport function minifyToolOutput(output: unknown): unknown {\n if (!output || typeof output !== \"object\") return output;\n const obj = output as Record<string, unknown>;\n\n // 1. Display-only tools: strip _displayData, keep message/summary\n if (\"_displayData\" in obj) {\n const { _displayData: _, ...contextData } = obj;\n return contextData;\n }\n\n // 2. searchKnowledgeBase: LLM already used results, no need to resend\n if (\"sources\" in obj && Array.isArray(obj.sources)) {\n return { _searched: true, totalResults: obj.totalResults };\n }\n\n // 3. Fallback: truncate any large outputs (>1.5 KB)\n const outputStr = JSON.stringify(obj);\n if (outputStr.length > 1500) {\n const summary: Record<string, unknown> = { _truncated: true };\n if (Array.isArray(obj)) {\n summary.itemCount = obj.length;\n } else {\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\" && v.length < 100) summary[k] = v;\n else if (typeof v === \"number\" || typeof v === \"boolean\") summary[k] = v;\n }\n }\n return summary;\n }\n\n return output;\n}\n\n/**\n * Prune and minify a messages array for sending to the API.\n *\n * 1. Keeps the first message (system / context) and the last `maxMessages - 1`.\n * 2. Deep-clones messages so the local UI state is not mutated.\n * 3. Strips large tool outputs via `minifyToolOutput`.\n *\n * @internal\n */\nexport function prepareMessages(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: any[],\n maxMessages: number,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any[] {\n let pruned = messages;\n\n if (messages.length > maxMessages) {\n pruned = [messages[0], ...messages.slice(-(maxMessages - 1))];\n }\n\n // Deep clone and minify tool outputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cloned = JSON.parse(JSON.stringify(pruned)) as any[];\n for (const msg of cloned) {\n if (msg.role === \"assistant\" && msg.parts) {\n for (const part of msg.parts) {\n if (part.type?.startsWith(\"tool-\") && part.output !== undefined) {\n part.output = minifyToolOutput(part.output);\n }\n }\n }\n }\n\n return cloned;\n}\n\n/**\n * Create a configured `DefaultChatTransport` instance from the AI SDK.\n *\n * The transport handles authentication, message pruning, tool-output\n * minification, and attaches project / session metadata to every request.\n *\n * Uses a dynamic `import(\"ai\")` so that `ai` stays an optional peer\n * dependency — the import is only resolved at call time.\n *\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A `DefaultChatTransport` instance ready for `useChat()`\n *\n * @example\n * ```ts\n * const transport = await createChatTransport(\n * { projectId: \"abc\", apiEndpoint: \"https://api.example.com\", apiKey: \"key\" },\n * { maxMessages: 20, getSessionId: () => sessionIdRef.current },\n * );\n * const { messages } = useChat({ transport });\n * ```\n */\nexport async function createChatTransport(\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const { DefaultChatTransport } = await import(\"ai\");\n\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n prepareSendMessagesRequest: ({ id, messages, trigger }) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n\n/**\n * Synchronous variant of `createChatTransport` for use when `ai`\n * is already bundled (i.e. not dynamically imported).\n *\n * Requires the caller to pass in the `DefaultChatTransport` constructor.\n *\n * @param DefaultChatTransport - The `DefaultChatTransport` class from `\"ai\"`\n * @param config - Chat backend configuration\n * @param options - Transport options\n * @returns A configured `DefaultChatTransport` instance\n */\nexport function createChatTransportSync(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n DefaultChatTransport: any,\n config: ChatConfig,\n options: CreateChatTransportOptions = {},\n) {\n const {\n maxMessages = 20,\n pageUrl,\n pageTitle,\n wpUserToken,\n getAnalyticsMessageId,\n getUserType,\n getSessionId,\n } = options;\n\n return new DefaultChatTransport({\n api: `${config.apiEndpoint}/api/kb/chat`,\n headers: () => {\n const headers: Record<string, string> = {};\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n return headers;\n },\n credentials: \"include\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n prepareSendMessagesRequest: ({ id, messages, trigger }: any) => {\n const prepared = prepareMessages(messages, maxMessages);\n\n return {\n body: {\n id,\n messages: prepared,\n trigger,\n projectId: config.projectId,\n sessionId: getSessionId?.() ?? options.sessionId,\n analyticsMessageId: getAnalyticsMessageId?.() ?? null,\n userType: getUserType?.() ?? options.userType ?? undefined,\n pageUrl,\n pageTitle,\n ...(wpUserToken ? { wpUserToken } : {}),\n },\n };\n },\n });\n}\n","\"use client\";\n\n/**\n * User type constants and helpers.\n *\n * Defines the available visitor personas that the `AgentDetection` tool\n * can assign. These are generic defaults — consumers can extend them via\n * configuration.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A visitor persona / user type definition.\n */\nexport interface UserType {\n /** Machine-readable identifier (e.g. `\"Guest\"`) */\n id: string;\n /** Human-readable label */\n label: string;\n /** Short description of this persona */\n description: string;\n /**\n * Icon identifier.\n *\n * In the SDK this is a string key (e.g. `\"User\"`, `\"Shield\"`, `\"Zap\"`)\n * rather than a Lucide component to avoid coupling core logic to a\n * specific icon library.\n */\n icon: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Default user types available for the `AgentDetection` tool.\n */\nexport const USER_TYPES: UserType[] = [\n {\n id: \"Guest\",\n label: \"Guest\",\n description: \"Just browsing\",\n icon: \"User\",\n },\n {\n id: \"Customer\",\n label: \"Customer\",\n description: \"Existing customer with questions\",\n icon: \"Shield\",\n },\n {\n id: \"Partner\",\n label: \"Partner\",\n description: \"Business partner or professional\",\n icon: \"Zap\",\n },\n];\n\n/**\n * Map from display label to user-type ID.\n *\n * Used to normalise user-type strings that come from the AI\n * (which may use the label rather than the ID).\n */\nexport const USER_TYPE_LABEL_MAP: Record<string, string> = {\n Guest: \"Guest\",\n Customer: \"Customer\",\n Partner: \"Partner\",\n};\n\n/**\n * Prefix for internal / hidden messages.\n *\n * Messages starting with this string are never rendered in the UI.\n */\nexport const INTERNAL_MESSAGE_PREFIX = \"[internal]\";\n\n/**\n * Check whether a message should be hidden from the UI.\n *\n * @param text - The raw message text\n * @returns `true` if the message is internal\n */\nexport function isInternalMessage(text: string): boolean {\n return text.startsWith(INTERNAL_MESSAGE_PREFIX);\n}\n"]}
|