@foisit/react-wrapper 2.4.2 → 2.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +0 -3
  2. package/index.js +3 -3
  3. package/index.mjs +69 -58
  4. package/package.json +15 -2
package/README.md CHANGED
@@ -554,8 +554,6 @@ function AccountManager() {
554
554
  ### Full Type Definitions
555
555
 
556
556
  ```tsx
557
- import { AssistantCommand, InteractiveResponse } from '@foisit/core';
558
-
559
557
  // Type-safe command definition
560
558
  const myCommand: AssistantCommand = {
561
559
  command: 'update settings',
@@ -668,7 +666,6 @@ test('renders assistant', () => {
668
666
 
669
667
  ## Related Packages
670
668
 
671
- - **[@foisit/core](../core)** - Core engine (auto-installed)
672
669
  - **[@foisit/angular-wrapper](../angular-wrapper)** - Angular integration
673
670
  - **[@foisit/vue-wrapper](../vue-wrapper)** - Vue integration
674
671
 
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("react/jsx-runtime"),C=require("react"),N={};function W(){return A.jsx("div",{className:N.container,children:A.jsx("h1",{children:"Welcome to ReactWrapper!"})})}class T{constructor(t){this.endpoint=t||"https://foisit-ninja.netlify.app/.netlify/functions/intent"}async determineIntent(t,e,i){try{const s={userInput:t,commands:e.map(r=>({id:r.id,command:r.command,description:r.description,parameters:r.parameters})),context:i},n=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!n.ok)throw new Error(`Proxy API Error: ${n.statusText}`);return await n.json()}catch(s){return console.error("OpenAIService Error:",s),{type:"unknown"}}}}class B{constructor(t=!0){if(this.commands=new Map,this.openAIService=null,this.context=null,this.pendingConfirmation=null,this.enableSmartIntent=!0,this.selectOptionsCache=new Map,typeof t=="boolean"){this.enableSmartIntent=t,this.enableSmartIntent&&(this.openAIService=new T);return}this.enableSmartIntent=t.enableSmartIntent??!0,this.enableSmartIntent&&(this.openAIService=new T(t.intentEndpoint))}addCommand(t,e){let i;if(typeof t=="string"){if(!e)throw new Error("Action required when adding command by string.");i={id:t.toLowerCase().replace(/\s+/g,"_"),command:t.toLowerCase(),action:e}}else i={...t},i.id||(i.id=i.command.toLowerCase().replace(/\s+/g,"_"));this.commands.set(i.command.toLowerCase(),i),i.id&&(i.id,i.command)}removeCommand(t){this.commands.delete(t.toLowerCase())}async executeCommand(t){if(typeof t=="object"&&t!==null){if(this.isStructured(t)){const c=String(t.commandId),f=t.params??{},a=this.getCommandById(c);if(!a)return{message:"That command is not available.",type:"error"};const p=this.sanitizeParamsForCommand(a,f),m=(a.parameters??[]).filter(S=>S.required).filter(S=>p[S.name]==null||p[S.name]==="");return m.length>0?(this.context={commandId:this.getCommandIdentifier(a),params:p},{message:`Please provide the required details for "${a.command}".`,type:"form",fields:m}):a.critical?(this.pendingConfirmation={commandId:this.getCommandIdentifier(a),params:p},this.buildConfirmResponse(a)):this.safeRunAction(a,p)}if(!this.context)return{message:"Session expired or invalid context.",type:"error"};const n=this.getCommandById(this.context.commandId);if(!n)return this.context=null,{message:"Session expired or invalid context.",type:"error"};if(Array.isArray(t))return{message:"Invalid form payload.",type:"error"};const o={...this.context.params,...t};if(n.critical)return this.context=null,this.pendingConfirmation={commandId:this.getCommandIdentifier(n),params:o},this.buildConfirmResponse(n);const r=await this.safeRunAction(n,o);return this.context=null,this.normalizeResponse(r)}const e=t.trim().toLowerCase();if(this.pendingConfirmation){const n=e;if(["yes","y","confirm","ok","okay"].includes(n)){const{commandId:o,params:r}=this.pendingConfirmation;this.pendingConfirmation=null;const c=this.getCommandById(o);return c?this.safeRunAction(c,r):{message:"That action is no longer available.",type:"error"}}return["no","n","cancel","stop"].includes(n)?(this.pendingConfirmation=null,{message:"✅ Cancelled.",type:"success"}):{message:"Please confirm: Yes or No.",type:"confirm",options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]}}const i=this.commands.get(e);if(i){const n=i,o=(n.parameters??[]).filter(r=>r.required);return o.length>0?(this.context={commandId:this.getCommandIdentifier(n),params:{}},{message:`Please provide the required details for "${n.command}".`,type:"form",fields:o}):n.critical?(this.pendingConfirmation={commandId:this.getCommandIdentifier(n),params:{}},this.buildConfirmResponse(n)):this.safeRunAction(n,{})}const s=await this.tryDeterministicMatch(e);if(s)return s;if(this.enableSmartIntent&&this.openAIService){const n=await this.getCommandsForAI(),o=await this.openAIService.determineIntent(e,n,this.context);return this.handleAIResult(o)}return this.enableSmartIntent?this.listAllCommands():{message:"I'm not sure what you mean.",type:"error"}}async handleAIResult(t){if(t.type==="match"&&t.match){const e=this.getCommandById(t.match);if(!e)return{message:"I'm not sure what you mean.",type:"error"};const i=t.params??{},s=this.sanitizeParamsForCommand(e,i),n=e.allowAiParamExtraction===!1?{}:s,r=(e.parameters??[]).filter(f=>f.required).filter(f=>n[f.name]==null||n[f.name]==="");if(t.incomplete||r.length>0){if(this.context={commandId:this.getCommandIdentifier(e),params:n},!(e.collectRequiredViaForm!==!1)&&this.shouldAskSingleQuestion(r)){const p=r.map(g=>g.name).join(" and ");return{message:t.message||`Please provide ${p}.`,type:"question"}}return{message:t.message||`Please fill in the missing details for "${e.command}".`,type:"form",fields:r}}if(e.critical)return this.pendingConfirmation={commandId:this.getCommandIdentifier(e),params:n},this.buildConfirmResponse(e);const c=await e.action(n);return this.normalizeResponse(c)}return t.type==="ambiguous"&&t.options&&t.options.length?{message:t.message||"Did you mean one of these?",type:"ambiguous",options:t.options.map(e=>({label:e.label,value:e.commandId??e.label,commandId:e.commandId}))}:this.listAllCommands()}sanitizeParamsForCommand(t,e){const i={...e??{}};for(const s of t.parameters??[]){const n=i[s.name];if(s.type==="string"){if(typeof n!="string"){delete i[s.name];continue}const o=n.trim();if(!o){delete i[s.name];continue}i[s.name]=o}if(s.type==="number"){const o=typeof n=="number"?n:Number(n==null?void 0:n.toString().trim());if(Number.isNaN(o)){delete i[s.name];continue}if(typeof s.min=="number"&&o<s.min){delete i[s.name];continue}if(typeof s.max=="number"&&o>s.max){delete i[s.name];continue}i[s.name]=o}if(s.type==="date"){const o=i[s.name];if(typeof o=="string"){const r=o.trim();this.isIsoDateString(r)?i[s.name]=r:delete i[s.name]}else delete i[s.name]}if(s.type==="select"){const o=typeof n=="string"?n:n==null?void 0:n.toString();if(!o){delete i[s.name];continue}if(Array.isArray(s.options)&&s.options.length>0&&!s.options.some(c=>String(c.value)===String(o))){delete i[s.name];continue}i[s.name]=o}if(s.type==="file"){const o=i[s.name],r=o&&typeof o=="object"&&typeof o.name=="string"&&typeof o.size=="number",c=typeof o=="string"&&/^data:[^;]+;base64,/.test(o);(s.delivery??"file")==="base64"?!c&&!r&&delete i[s.name]:r||delete i[s.name]}}return i}isIsoDateString(t){if(!/^\d{4}-\d{2}-\d{2}$/.test(t))return!1;const e=new Date(`${t}T00:00:00Z`);return!Number.isNaN(e.getTime())}shouldAskSingleQuestion(t){if(t.length!==1)return!1;const e=t[0].type;return e==="string"||e==="number"||e==="date"}buildConfirmResponse(t){return{message:`⚠️ Are you sure you want to run "${t.command}"?`,type:"confirm",options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]}}async tryDeterministicMatch(t){const e=[];for(const r of this.commands.values()){let c=0;const f=r.command.toLowerCase();t.includes(f)&&(c+=5);const a=r.keywords??[];for(const p of a){const g=p.toLowerCase().trim();g&&(t===g?c+=4:t.includes(g)&&(c+=3))}c>0&&e.push({cmd:r,score:c})}if(e.length===0)return null;e.sort((r,c)=>c.score-r.score);const i=e[0].score,s=e.filter(r=>r.score===i).slice(0,3);if(s.length>1)return{message:"I think you mean one of these. Which one should I run?",type:"ambiguous",options:s.map(r=>({label:r.cmd.command,value:r.cmd.command,commandId:r.cmd.id}))};const n=s[0].cmd,o=(n.parameters??[]).filter(r=>r.required);return o.length>0?(this.context={commandId:this.getCommandIdentifier(n),params:{}},{message:`Please provide the required details for "${n.command}".`,type:"form",fields:o}):n.critical?(this.pendingConfirmation={commandId:this.getCommandIdentifier(n),params:{}},this.buildConfirmResponse(n)):this.safeRunAction(n,{})}async safeRunAction(t,e){try{const i=await t.action(e??{});return this.normalizeResponse(i)}catch{return{message:"Something went wrong while running that command.",type:"error"}}}async getCommandsForAI(){const t=Array.from(this.commands.values()).map(e=>({...e,parameters:e.parameters?e.parameters.map(i=>({...i})):void 0}));return await Promise.all(t.map(async e=>{e.parameters&&await Promise.all(e.parameters.map(async i=>{if(i.type!=="select"||!i.getOptions||i.options&&i.options.length)return;const s=`${e.id??e.command}:${i.name}`,n=this.selectOptionsCache.get(s),o=Date.now();if(n&&o-n.ts<6e4){i.options=n.options;return}try{const r=await i.getOptions();this.selectOptionsCache.set(s,{options:r,ts:o}),i.options=r}catch{}}))})),t}getCommandById(t){for(const e of this.commands.values())if(e.id===t)return e}listAllCommands(){return{message:"Here are the available commands:",type:"ambiguous",options:Array.from(this.commands.values()).map(e=>({label:e.command,value:e.id??e.command,commandId:e.id??e.command}))}}normalizeResponse(t){return typeof t=="string"?{message:t,type:"success"}:t&&typeof t=="object"?t:{message:"Done",type:"success"}}isStructured(t){return typeof t.commandId=="string"}getCommandIdentifier(t){return t.id||(t.id=t.command.toLowerCase().replace(/\s+/g,"_")),t.id}getCommands(){return Array.from(this.commands.keys())}}class q{constructor(){this.synth=window.speechSynthesis}speak(t,e){if(!this.synth){console.error("SpeechSynthesis API is not supported in this browser.");return}const i=new SpeechSynthesisUtterance(t);e&&(i.pitch=e.pitch||1,i.rate=e.rate||1,i.volume=e.volume||1),i.onstart=()=>{window.dispatchEvent(new CustomEvent("foisit:tts-start"))},i.onend=()=>{console.log("Speech finished."),window.dispatchEvent(new CustomEvent("foisit:tts-end"))},i.onerror=s=>{console.error("Error during speech synthesis:",s.error)},this.synth.speak(i)}stopSpeaking(){this.synth&&this.synth.cancel()}}class z{constructor(){this.fallbackMessage="Sorry, I didn’t understand that."}setFallbackMessage(t){this.fallbackMessage=t}handleFallback(t){t&&console.log(`Fallback triggered for: "${t}"`),console.log(this.fallbackMessage),new q().speak(this.fallbackMessage)}getFallbackMessage(){return this.fallbackMessage}}const P=()=>{const d=window;return d.SpeechRecognition??d.webkitSpeechRecognition??null};class O{constructor(t="en-US",e={}){this.recognition=null,this.isListening=!1,this.engineActive=!1,this.intentionallyStopped=!1,this.restartAllowed=!0,this.lastStart=0,this.backoffMs=250,this.destroyed=!1,this.resultCallback=null,this.ttsSpeaking=!1,this.debugEnabled=!0,this.restartTimer=null,this.prewarmed=!1,this.hadResultThisSession=!1,this.onTTSStart=()=>{var s;this.ttsSpeaking=!0;try{(s=this.recognition)==null||s.stop()}catch{}this.isListening&&this.emitStatus("speaking")},this.onTTSEnd=()=>{this.ttsSpeaking=!1,this.isListening&&this.restartAllowed?this.safeRestart():this.emitStatus(this.isListening?"listening":"idle")};const i=P();if(i){this.recognition=new i,this.recognition.lang=t,this.recognition.interimResults=e.interimResults??!0,this.recognition.continuous=e.continuous??!0,this.recognition.onresult=n=>this.handleResult(n,e),this.recognition.onend=()=>this.handleEnd(),this.recognition.onstart=()=>{this.log("recognition onstart"),this.engineActive=!0,this.hadResultThisSession=!1,this.restartTimer&&(clearTimeout(this.restartTimer),this.restartTimer=null),this.backoffMs=250,this.isListening&&!this.ttsSpeaking&&this.emitStatus("listening")};const s=this.recognition;s.onaudiostart=()=>this.log("onaudiostart"),s.onsoundstart=()=>this.log("onsoundstart"),s.onspeechstart=()=>this.log("onspeechstart"),s.onspeechend=()=>this.log("onspeechend"),s.onsoundend=()=>this.log("onsoundend"),s.onaudioend=()=>this.log("onaudioend"),this.recognition.onerror=n=>this.handleError(n)}else this.recognition=null,this.emitStatus("unsupported");window.addEventListener("foisit:tts-start",this.onTTSStart),window.addEventListener("foisit:tts-end",this.onTTSEnd),this.visibilityHandler=()=>{var s;if(document.hidden){try{(s=this.recognition)==null||s.stop()}catch{}this.emitStatus(this.ttsSpeaking?"speaking":"idle")}else this.isListening&&!this.ttsSpeaking&&this.safeRestart()},document.addEventListener("visibilitychange",this.visibilityHandler)}log(t){this.debugEnabled&&t&&console.log("[VoiceProcessor]",t)}warn(t){this.debugEnabled&&t&&console.warn("[VoiceProcessor]",t)}error(t){this.debugEnabled&&t&&console.error("[VoiceProcessor]",t)}isSupported(){return P()!==null}onStatusChange(t){this.statusCallback=t}startListening(t){if(!this.isSupported()||!this.recognition){this.warn("VoiceProcessor: SpeechRecognition is not supported in this browser."),this.emitStatus("unsupported");return}if(this.isListening){this.warn("VoiceProcessor: Already listening."),this.resultCallback=t;return}this.resultCallback=t,this.intentionallyStopped=!1,this.restartAllowed=!0,this.isListening=!0,this.emitStatus("listening"),this.prewarmAudio().finally(()=>{this.safeRestart()})}stopListening(){var t;this.intentionallyStopped=!0,this.restartAllowed=!1,this.isListening=!1,this.emitStatus(this.ttsSpeaking?"speaking":"idle");try{(t=this.recognition)==null||t.stop()}catch{}}destroy(){this.destroyed=!0,this.stopListening(),this.resultCallback=null,window.removeEventListener("foisit:tts-start",this.onTTSStart),window.removeEventListener("foisit:tts-end",this.onTTSEnd),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=void 0)}handleResult(t,e){var s,n;if(!this.resultCallback)return;const i=e.confidenceThreshold??.6;for(let o=t.resultIndex;o<t.results.length;o++){const r=t.results[o],c=r&&r[0],f=((n=(s=c==null?void 0:c.transcript)==null?void 0:s.trim)==null?void 0:n.call(s))||"",a=(c==null?void 0:c.confidence)??0;if(f&&!(!r.isFinal&&e.interimResults===!1)&&!(r.isFinal&&a<i))try{this.hadResultThisSession=!0,this.resultCallback(f,!!r.isFinal)}catch{this.error("VoiceProcessor: result callback error")}}}handleEnd(){if(this.log("recognition onend"),this.engineActive=!1,this.destroyed||this.intentionallyStopped||!this.restartAllowed||this.ttsSpeaking){this.ttsSpeaking||(this.isListening=!1,this.emitStatus("idle"));return}this.isListening=!0,this.scheduleRestart()}handleError(t){const e=t==null?void 0:t.error;if(this.warn(`Error occurred: ${e??"unknown"}`),e&&["not-allowed","service-not-allowed","bad-grammar","language-not-supported"].includes(e)){this.intentionallyStopped=!0,this.restartAllowed=!1,this.isListening=!1,this.emitStatus("error",{error:e});return}this.scheduleRestart()}safeRestart(){if(!this.recognition)return;if(this.engineActive){this.log("safeRestart: engine already active, skipping start");return}const t=Date.now();if(t-this.lastStart<300){setTimeout(()=>this.safeRestart(),300);return}this.lastStart=t;try{this.log("calling recognition.start()"),this.recognition.start(),this.backoffMs=250,this.isListening&&!this.ttsSpeaking&&this.emitStatus("listening")}catch{this.error("recognition.start() threw; scheduling restart"),this.scheduleRestart()}}scheduleRestart(){if(this.destroyed||this.intentionallyStopped||!this.restartAllowed||this.ttsSpeaking)return;if(this.engineActive){this.log("scheduleRestart: engine active, not scheduling");return}const t=Math.min(this.backoffMs,2e3);if(this.log(`scheduleRestart in ${t}ms`),this.restartTimer){this.log("scheduleRestart: restart already scheduled");return}this.restartTimer=setTimeout(()=>{this.restartTimer=null,!(this.destroyed||this.intentionallyStopped||!this.restartAllowed||this.ttsSpeaking)&&this.safeRestart()},t),this.backoffMs=Math.min(this.backoffMs*2,2e3)}async prewarmAudio(){if(!this.prewarmed)try{if(typeof navigator>"u"||!("mediaDevices"in navigator))return;const t=navigator.mediaDevices;if(!(t!=null&&t.getUserMedia))return;this.log("prewarmAudio: requesting mic");const e=await t.getUserMedia({audio:!0});for(const i of e.getTracks())i.stop();this.prewarmed=!0,this.log("prewarmAudio: mic ready")}catch{this.warn("prewarmAudio: failed to get mic")}}emitStatus(t,e){if(this.statusCallback)try{this.statusCallback(t,e)}catch{this.error("VoiceProcessor: status callback error")}}}class j{constructor(){this.lastTap=0}setupDoubleTapListener(t){this.destroy(),this.dblClickListener=()=>{t()},document.addEventListener("dblclick",this.dblClickListener),this.touchEndListener=()=>{const e=new Date().getTime(),i=e-this.lastTap;i<300&&i>0&&t(),this.lastTap=e},document.addEventListener("touchend",this.touchEndListener)}destroy(){this.dblClickListener&&document.removeEventListener("dblclick",this.dblClickListener),this.touchEndListener&&document.removeEventListener("touchend",this.touchEndListener),this.dblClickListener=void 0,this.touchEndListener=void 0}}function U(){if(document.querySelector("#assistant-styles")){console.log("Styles already injected");return}const t=document.createElement("style");t.id="assistant-styles",t.innerHTML=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("react/jsx-runtime"),C=require("react"),N={};function W(){return A.jsx("div",{className:N.container,children:A.jsx("h1",{children:"Welcome to ReactWrapper!"})})}class T{constructor(t){this.endpoint=t||"https://foisit-ninja.netlify.app/.netlify/functions/intent"}async determineIntent(t,e,i){try{const s={userInput:t,commands:e.map(r=>({id:r.id,command:r.command,description:r.description,parameters:r.parameters})),context:i},n=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!n.ok)throw new Error(`Proxy API Error: ${n.statusText}`);return await n.json()}catch(s){return console.error("OpenAIService Error:",s),{type:"unknown"}}}}class B{constructor(t=!0){if(this.commands=new Map,this.openAIService=null,this.context=null,this.pendingConfirmation=null,this.enableSmartIntent=!0,this.selectOptionsCache=new Map,typeof t=="boolean"){this.enableSmartIntent=t,this.enableSmartIntent&&(this.openAIService=new T);return}this.enableSmartIntent=t.enableSmartIntent??!0,this.enableSmartIntent&&(this.openAIService=new T(t.intentEndpoint))}addCommand(t,e){let i;if(typeof t=="string"){if(!e)throw new Error("Action required when adding command by string.");i={id:t.toLowerCase().replace(/\s+/g,"_"),command:t.toLowerCase(),action:e}}else i={...t},i.id||(i.id=i.command.toLowerCase().replace(/\s+/g,"_"));this.commands.set(i.command.toLowerCase(),i),i.id&&(i.id,i.command)}removeCommand(t){this.commands.delete(t.toLowerCase())}async executeCommand(t){if(typeof t=="object"&&t!==null){if(this.isStructured(t)){const c=String(t.commandId),f=t.params??{},a=this.getCommandById(c);if(!a)return{message:"That command is not available.",type:"error"};const p=this.sanitizeParamsForCommand(a,f),m=(a.parameters??[]).filter(S=>S.required).filter(S=>p[S.name]==null||p[S.name]==="");return m.length>0?(this.context={commandId:this.getCommandIdentifier(a),params:p},{message:`Please provide the required details for "${a.command}".`,type:"form",fields:m}):a.critical?(this.pendingConfirmation={commandId:this.getCommandIdentifier(a),params:p},this.buildConfirmResponse(a)):this.safeRunAction(a,p)}if(!this.context)return{message:"Session expired or invalid context.",type:"error"};const n=this.getCommandById(this.context.commandId);if(!n)return this.context=null,{message:"Session expired or invalid context.",type:"error"};if(Array.isArray(t))return{message:"Invalid form payload.",type:"error"};const o={...this.context.params,...t};if(n.critical)return this.context=null,this.pendingConfirmation={commandId:this.getCommandIdentifier(n),params:o},this.buildConfirmResponse(n);const r=await this.safeRunAction(n,o);return this.context=null,this.normalizeResponse(r)}const e=t.trim().toLowerCase();if(this.pendingConfirmation){const n=e;if(["yes","y","confirm","ok","okay"].includes(n)){const{commandId:o,params:r}=this.pendingConfirmation;this.pendingConfirmation=null;const c=this.getCommandById(o);return c?this.safeRunAction(c,r):{message:"That action is no longer available.",type:"error"}}return["no","n","cancel","stop"].includes(n)?(this.pendingConfirmation=null,{message:"Cancelled.",type:"success"}):{message:"Please confirm: Yes or No.",type:"confirm",options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]}}const i=this.commands.get(e);if(i){const n=i,o=(n.parameters??[]).filter(r=>r.required);return o.length>0?(this.context={commandId:this.getCommandIdentifier(n),params:{}},{message:`Please provide the required details for "${n.command}".`,type:"form",fields:o}):n.critical?(this.pendingConfirmation={commandId:this.getCommandIdentifier(n),params:{}},this.buildConfirmResponse(n)):this.safeRunAction(n,{})}const s=await this.tryDeterministicMatch(e);if(s)return s;if(this.enableSmartIntent&&this.openAIService){const n=await this.getCommandsForAI(),o=await this.openAIService.determineIntent(e,n,this.context);return this.handleAIResult(o)}return this.enableSmartIntent?this.listAllCommands():{message:"I'm not sure what you mean.",type:"error"}}async handleAIResult(t){if(t.type==="match"&&t.match){const e=this.getCommandById(t.match);if(!e)return{message:"I'm not sure what you mean.",type:"error"};const i=t.params??{},s=this.sanitizeParamsForCommand(e,i),n=e.allowAiParamExtraction===!1?{}:s,r=(e.parameters??[]).filter(f=>f.required).filter(f=>n[f.name]==null||n[f.name]==="");if(t.incomplete||r.length>0){if(this.context={commandId:this.getCommandIdentifier(e),params:n},!(e.collectRequiredViaForm!==!1)&&this.shouldAskSingleQuestion(r)){const p=r.map(g=>g.name).join(" and ");return{message:t.message||`Please provide ${p}.`,type:"question"}}return{message:t.message||`Please fill in the missing details for "${e.command}".`,type:"form",fields:r}}if(e.critical)return this.pendingConfirmation={commandId:this.getCommandIdentifier(e),params:n},this.buildConfirmResponse(e);const c=await e.action(n);return this.normalizeResponse(c)}return t.type==="ambiguous"&&t.options&&t.options.length?{message:t.message||"Did you mean one of these?",type:"ambiguous",options:t.options.map(e=>({label:e.label,value:e.commandId??e.label,commandId:e.commandId}))}:this.listAllCommands()}sanitizeParamsForCommand(t,e){const i={...e??{}};for(const s of t.parameters??[]){const n=i[s.name];if(s.type==="string"){if(typeof n!="string"){delete i[s.name];continue}const o=n.trim();if(!o){delete i[s.name];continue}i[s.name]=o}if(s.type==="number"){const o=typeof n=="number"?n:Number(n==null?void 0:n.toString().trim());if(Number.isNaN(o)){delete i[s.name];continue}if(typeof s.min=="number"&&o<s.min){delete i[s.name];continue}if(typeof s.max=="number"&&o>s.max){delete i[s.name];continue}i[s.name]=o}if(s.type==="date"){const o=i[s.name];if(typeof o=="string"){const r=o.trim();this.isIsoDateString(r)?i[s.name]=r:delete i[s.name]}else delete i[s.name]}if(s.type==="select"){const o=typeof n=="string"?n:n==null?void 0:n.toString();if(!o){delete i[s.name];continue}if(Array.isArray(s.options)&&s.options.length>0&&!s.options.some(c=>String(c.value)===String(o))){delete i[s.name];continue}i[s.name]=o}if(s.type==="file"){const o=i[s.name],r=o&&typeof o=="object"&&typeof o.name=="string"&&typeof o.size=="number",c=typeof o=="string"&&/^data:[^;]+;base64,/.test(o);(s.delivery??"file")==="base64"?!c&&!r&&delete i[s.name]:r||delete i[s.name]}}return i}isIsoDateString(t){if(!/^\d{4}-\d{2}-\d{2}$/.test(t))return!1;const e=new Date(`${t}T00:00:00Z`);return!Number.isNaN(e.getTime())}shouldAskSingleQuestion(t){if(t.length!==1)return!1;const e=t[0].type;return e==="string"||e==="number"||e==="date"}buildConfirmResponse(t){return{message:`Are you sure you want to run "${t.command}"?`,type:"confirm",options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]}}async tryDeterministicMatch(t){const e=[];for(const r of this.commands.values()){let c=0;const f=r.command.toLowerCase();t.includes(f)&&(c+=5);const a=r.keywords??[];for(const p of a){const g=p.toLowerCase().trim();g&&(t===g?c+=4:t.includes(g)&&(c+=3))}c>0&&e.push({cmd:r,score:c})}if(e.length===0)return null;e.sort((r,c)=>c.score-r.score);const i=e[0].score,s=e.filter(r=>r.score===i).slice(0,3);if(s.length>1)return{message:"I think you mean one of these. Which one should I run?",type:"ambiguous",options:s.map(r=>({label:r.cmd.command,value:r.cmd.command,commandId:r.cmd.id}))};const n=s[0].cmd,o=(n.parameters??[]).filter(r=>r.required);return o.length>0?(this.context={commandId:this.getCommandIdentifier(n),params:{}},{message:`Please provide the required details for "${n.command}".`,type:"form",fields:o}):n.critical?(this.pendingConfirmation={commandId:this.getCommandIdentifier(n),params:{}},this.buildConfirmResponse(n)):this.safeRunAction(n,{})}async safeRunAction(t,e){try{const i=await t.action(e??{});return this.normalizeResponse(i)}catch{return{message:"Something went wrong while running that command.",type:"error"}}}async getCommandsForAI(){const t=Array.from(this.commands.values()).map(e=>({...e,parameters:e.parameters?e.parameters.map(i=>({...i})):void 0}));return await Promise.all(t.map(async e=>{e.parameters&&await Promise.all(e.parameters.map(async i=>{if(i.type!=="select"||!i.getOptions||i.options&&i.options.length)return;const s=`${e.id??e.command}:${i.name}`,n=this.selectOptionsCache.get(s),o=Date.now();if(n&&o-n.ts<6e4){i.options=n.options;return}try{const r=await i.getOptions();this.selectOptionsCache.set(s,{options:r,ts:o}),i.options=r}catch{}}))})),t}getCommandById(t){for(const e of this.commands.values())if(e.id===t)return e}listAllCommands(){return{message:"Here are the available commands:",type:"ambiguous",options:Array.from(this.commands.values()).map(e=>({label:e.command,value:e.id??e.command,commandId:e.id??e.command}))}}normalizeResponse(t){return typeof t=="string"?{message:t,type:"success"}:t&&typeof t=="object"?t:{message:"Done",type:"success"}}isStructured(t){return typeof t.commandId=="string"}getCommandIdentifier(t){return t.id||(t.id=t.command.toLowerCase().replace(/\s+/g,"_")),t.id}getCommands(){return Array.from(this.commands.keys())}}class H{constructor(){this.synth=typeof window<"u"?window.speechSynthesis:null}speak(t,e){if(!this.synth){console.error("SpeechSynthesis API is not supported in this environment.");return}const i=new SpeechSynthesisUtterance(t);e&&(i.pitch=e.pitch||1,i.rate=e.rate||1,i.volume=e.volume||1),typeof window<"u"&&(i.onstart=()=>{window.dispatchEvent(new CustomEvent("foisit:tts-start"))},i.onend=()=>{console.log("Speech finished."),window.dispatchEvent(new CustomEvent("foisit:tts-end"))}),i.onerror=s=>{console.error("Error during speech synthesis:",s.error)},this.synth.speak(i)}stopSpeaking(){this.synth&&this.synth.cancel()}}class z{constructor(){this.fallbackMessage="Sorry, I didn’t understand that."}setFallbackMessage(t){this.fallbackMessage=t}handleFallback(t){t&&console.log(`Fallback triggered for: "${t}"`),console.log(this.fallbackMessage),new H().speak(this.fallbackMessage)}getFallbackMessage(){return this.fallbackMessage}}const P=()=>{if(typeof window>"u")return null;const d=window;return d.SpeechRecognition??d.webkitSpeechRecognition??null};class O{constructor(t="en-US",e={}){this.recognition=null,this.isListening=!1,this.engineActive=!1,this.intentionallyStopped=!1,this.restartAllowed=!0,this.lastStart=0,this.backoffMs=250,this.destroyed=!1,this.resultCallback=null,this.ttsSpeaking=!1,this.debugEnabled=!0,this.restartTimer=null,this.prewarmed=!1,this.hadResultThisSession=!1,this.onTTSStart=()=>{var s;this.ttsSpeaking=!0;try{(s=this.recognition)==null||s.stop()}catch{}this.isListening&&this.emitStatus("speaking")},this.onTTSEnd=()=>{this.ttsSpeaking=!1,this.isListening&&this.restartAllowed?this.safeRestart():this.emitStatus(this.isListening?"listening":"idle")};const i=P();if(i){this.recognition=new i,this.recognition.lang=t,this.recognition.interimResults=e.interimResults??!0,this.recognition.continuous=e.continuous??!0,this.recognition.onresult=n=>this.handleResult(n,e),this.recognition.onend=()=>this.handleEnd(),this.recognition.onstart=()=>{this.log("recognition onstart"),this.engineActive=!0,this.hadResultThisSession=!1,this.restartTimer&&(clearTimeout(this.restartTimer),this.restartTimer=null),this.backoffMs=250,this.isListening&&!this.ttsSpeaking&&this.emitStatus("listening")};const s=this.recognition;s.onaudiostart=()=>this.log("onaudiostart"),s.onsoundstart=()=>this.log("onsoundstart"),s.onspeechstart=()=>this.log("onspeechstart"),s.onspeechend=()=>this.log("onspeechend"),s.onsoundend=()=>this.log("onsoundend"),s.onaudioend=()=>this.log("onaudioend"),this.recognition.onerror=n=>this.handleError(n)}else this.recognition=null,this.emitStatus("unsupported");typeof window<"u"?(window.addEventListener("foisit:tts-start",this.onTTSStart),window.addEventListener("foisit:tts-end",this.onTTSEnd),this.visibilityHandler=()=>{var s;if(typeof document<"u"&&document.hidden){try{(s=this.recognition)==null||s.stop()}catch{}this.emitStatus(this.ttsSpeaking?"speaking":"idle")}else this.isListening&&!this.ttsSpeaking&&this.safeRestart()},typeof document<"u"&&document.addEventListener("visibilitychange",this.visibilityHandler)):this.visibilityHandler=void 0}log(t){this.debugEnabled&&t&&console.log("[VoiceProcessor]",t)}warn(t){this.debugEnabled&&t&&console.warn("[VoiceProcessor]",t)}error(t){this.debugEnabled&&t&&console.error("[VoiceProcessor]",t)}isSupported(){return P()!==null}onStatusChange(t){this.statusCallback=t}startListening(t){if(!this.isSupported()||!this.recognition){this.warn("VoiceProcessor: SpeechRecognition is not supported in this browser."),this.emitStatus("unsupported");return}if(this.isListening){this.warn("VoiceProcessor: Already listening."),this.resultCallback=t;return}this.resultCallback=t,this.intentionallyStopped=!1,this.restartAllowed=!0,this.isListening=!0,this.emitStatus("listening"),this.prewarmAudio().finally(()=>{this.safeRestart()})}stopListening(){var t;this.intentionallyStopped=!0,this.restartAllowed=!1,this.isListening=!1,this.emitStatus(this.ttsSpeaking?"speaking":"idle");try{(t=this.recognition)==null||t.stop()}catch{}}destroy(){this.destroyed=!0,this.stopListening(),this.resultCallback=null,window.removeEventListener("foisit:tts-start",this.onTTSStart),window.removeEventListener("foisit:tts-end",this.onTTSEnd),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=void 0)}handleResult(t,e){var s,n;if(!this.resultCallback)return;const i=e.confidenceThreshold??.6;for(let o=t.resultIndex;o<t.results.length;o++){const r=t.results[o],c=r&&r[0],f=((n=(s=c==null?void 0:c.transcript)==null?void 0:s.trim)==null?void 0:n.call(s))||"",a=(c==null?void 0:c.confidence)??0;if(f&&!(!r.isFinal&&e.interimResults===!1)&&!(r.isFinal&&a<i))try{this.hadResultThisSession=!0,this.resultCallback(f,!!r.isFinal)}catch{this.error("VoiceProcessor: result callback error")}}}handleEnd(){if(this.log("recognition onend"),this.engineActive=!1,this.destroyed||this.intentionallyStopped||!this.restartAllowed||this.ttsSpeaking){this.ttsSpeaking||(this.isListening=!1,this.emitStatus("idle"));return}this.isListening=!0,this.scheduleRestart()}handleError(t){const e=t==null?void 0:t.error;if(this.warn(`Error occurred: ${e??"unknown"}`),e&&["not-allowed","service-not-allowed","bad-grammar","language-not-supported"].includes(e)){this.intentionallyStopped=!0,this.restartAllowed=!1,this.isListening=!1,this.emitStatus("error",{error:e});return}this.scheduleRestart()}safeRestart(){if(!this.recognition)return;if(this.engineActive){this.log("safeRestart: engine already active, skipping start");return}const t=Date.now();if(t-this.lastStart<300){setTimeout(()=>this.safeRestart(),300);return}this.lastStart=t;try{this.log("calling recognition.start()"),this.recognition.start(),this.backoffMs=250,this.isListening&&!this.ttsSpeaking&&this.emitStatus("listening")}catch{this.error("recognition.start() threw; scheduling restart"),this.scheduleRestart()}}scheduleRestart(){if(this.destroyed||this.intentionallyStopped||!this.restartAllowed||this.ttsSpeaking)return;if(this.engineActive){this.log("scheduleRestart: engine active, not scheduling");return}const t=Math.min(this.backoffMs,2e3);if(this.log(`scheduleRestart in ${t}ms`),this.restartTimer){this.log("scheduleRestart: restart already scheduled");return}this.restartTimer=setTimeout(()=>{this.restartTimer=null,!(this.destroyed||this.intentionallyStopped||!this.restartAllowed||this.ttsSpeaking)&&this.safeRestart()},t),this.backoffMs=Math.min(this.backoffMs*2,2e3)}async prewarmAudio(){if(!this.prewarmed)try{if(typeof navigator>"u"||!("mediaDevices"in navigator))return;const t=navigator.mediaDevices;if(!(t!=null&&t.getUserMedia))return;this.log("prewarmAudio: requesting mic");const e=await t.getUserMedia({audio:!0});for(const i of e.getTracks())i.stop();this.prewarmed=!0,this.log("prewarmAudio: mic ready")}catch{this.warn("prewarmAudio: failed to get mic")}}emitStatus(t,e){if(this.statusCallback)try{this.statusCallback(t,e)}catch{this.error("VoiceProcessor: status callback error")}}}class j{constructor(){this.lastTap=0}setupDoubleTapListener(t){this.destroy(),this.dblClickListener=()=>{t()},document.addEventListener("dblclick",this.dblClickListener),this.touchEndListener=()=>{const e=new Date().getTime(),i=e-this.lastTap;i<300&&i>0&&t(),this.lastTap=e},document.addEventListener("touchend",this.touchEndListener)}destroy(){this.dblClickListener&&document.removeEventListener("dblclick",this.dblClickListener),this.touchEndListener&&document.removeEventListener("touchend",this.touchEndListener),this.dblClickListener=void 0,this.touchEndListener=void 0}}function U(){if(document.querySelector("#assistant-styles")){console.log("Styles already injected");return}const t=document.createElement("style");t.id="assistant-styles",t.innerHTML=`
2
2
  /* Rounded shape with gradient animation */
3
3
  .gradient-indicator {
4
4
  position: fixed;
@@ -31,7 +31,7 @@
31
31
  border-radius: 50%;
32
32
  }
33
33
  }
34
- `,document.head.appendChild(t),console.log("Gradient styles injected")}function D(){if(document.querySelector("#gradient-indicator"))return;const d=document.createElement("div");d.id="gradient-indicator",U(),d.classList.add("gradient-indicator"),document.body.appendChild(d),console.log("Gradient indicator added to the DOM")}function $(){const d=document.querySelector("#gradient-indicator");d&&(d.remove(),console.log("Gradient indicator removed from the DOM"))}class V{constructor(){this.state="idle",this.subscribers=[]}getState(){return this.state}setState(t){this.state=t,this.notifySubscribers(),console.log("State updated:",t),t==="listening"?D():$()}subscribe(t){this.subscribers.push(t)}notifySubscribers(){this.subscribers.forEach(t=>t(this.state))}}class G{constructor(t){this.container=null,this.chatWindow=null,this.messagesContainer=null,this.input=null,this.isOpen=!1,this.loadingEl=null,this.config=t,this.init()}init(){var e,i;if(this.container)return;this.injectOverlayStyles();const t=document.getElementById("foisit-overlay-container");if(t&&t instanceof HTMLElement){this.container=t,this.chatWindow=t.querySelector(".foisit-chat"),this.messagesContainer=t.querySelector(".foisit-messages"),this.input=t.querySelector("input.foisit-input"),((e=this.config.floatingButton)==null?void 0:e.visible)!==!1&&!t.querySelector(".foisit-floating-btn")&&this.renderFloatingButton(),this.chatWindow||this.renderChatWindow();return}this.container=document.createElement("div"),this.container.id="foisit-overlay-container",this.container.className="foisit-overlay-container",document.body.appendChild(this.container),((i=this.config.floatingButton)==null?void 0:i.visible)!==!1&&this.renderFloatingButton(),this.renderChatWindow()}renderFloatingButton(){var s,n,o,r,c,f;const t=document.createElement("button");t.innerHTML=((s=this.config.floatingButton)==null?void 0:s.customHtml)||"🎙️";const e=((o=(n=this.config.floatingButton)==null?void 0:n.position)==null?void 0:o.bottom)||"20px",i=((c=(r=this.config.floatingButton)==null?void 0:r.position)==null?void 0:c.right)||"20px";t.className="foisit-floating-btn",t.style.bottom=e,t.style.right=i,t.onclick=()=>this.toggle(),t.onmouseenter=()=>t.style.transform="scale(1.05)",t.onmouseleave=()=>t.style.transform="scale(1)",(f=this.container)==null||f.appendChild(t)}renderChatWindow(){var n;if(this.chatWindow)return;this.chatWindow=document.createElement("div"),this.chatWindow.className="foisit-chat";const t=document.createElement("div");t.className="foisit-header";const e=document.createElement("span");e.className="foisit-title",e.textContent="Foisit";const i=document.createElement("button");i.type="button",i.className="foisit-close",i.setAttribute("aria-label","Close"),i.innerHTML="&times;",i.addEventListener("click",()=>this.toggle()),t.appendChild(e),t.appendChild(i),this.messagesContainer=document.createElement("div"),this.messagesContainer.className="foisit-messages";const s=document.createElement("div");s.className="foisit-input-area",this.input=document.createElement("input"),this.input.placeholder=this.config.inputPlaceholder||"Type a command...",this.input.className="foisit-input",this.input.addEventListener("keydown",o=>{var r;if(o.key==="Enter"&&((r=this.input)!=null&&r.value.trim())){const c=this.input.value.trim();this.input.value="",this.onSubmit&&this.onSubmit(c)}}),s.appendChild(this.input),this.chatWindow.appendChild(t),this.chatWindow.appendChild(this.messagesContainer),this.chatWindow.appendChild(s),(n=this.container)==null||n.appendChild(this.chatWindow)}registerCallbacks(t,e){this.onSubmit=t,this.onClose=e}toggle(t,e){t&&(this.onSubmit=t),e&&(this.onClose=e),this.isOpen=!this.isOpen,this.chatWindow&&(this.isOpen?(this.chatWindow.style.display="flex",requestAnimationFrame(()=>{this.chatWindow&&(this.chatWindow.style.opacity="1",this.chatWindow.style.transform="translateY(0) scale(1)")}),setTimeout(()=>{var i;return(i=this.input)==null?void 0:i.focus()},100)):(this.chatWindow.style.opacity="0",this.chatWindow.style.transform="translateY(20px) scale(0.95)",setTimeout(()=>{this.chatWindow&&!this.isOpen&&(this.chatWindow.style.display="none")},200),this.onClose&&this.onClose()))}addMessage(t,e){if(!this.messagesContainer)return;const i=document.createElement("div");i.textContent=t,i.className=e==="user"?"foisit-bubble user":"foisit-bubble system",this.messagesContainer.appendChild(i),this.scrollToBottom()}addOptions(t){if(!this.messagesContainer)return;const e=document.createElement("div");e.className="foisit-options-container",t.forEach(i=>{const s=document.createElement("button");s.textContent=i.label,s.className="foisit-option-chip",s.setAttribute("type","button"),s.setAttribute("aria-label",i.label);const n=()=>{if(i.commandId){this.onSubmit&&this.onSubmit({commandId:i.commandId});return}const o=i&&typeof i.value=="string"&&i.value.trim()?i.value:i.label;this.onSubmit&&this.onSubmit(o)};s.onclick=n,s.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),n())},e.appendChild(s)}),this.messagesContainer.appendChild(e),this.scrollToBottom()}addForm(t,e,i){if(!this.messagesContainer)return;this.addMessage(t,"system");const s=document.createElement("form");s.className="foisit-form";const n=[],o=(a,p)=>{const g=document.createElement("div");return g.className="foisit-form-label",g.innerHTML=a+(p?' <span class="foisit-req-star">*</span>':""),g},r=()=>{const a=document.createElement("div");return a.className="foisit-form-error",a.style.display="none",a};(e??[]).forEach(a=>{const p=document.createElement("div");p.className="foisit-form-group";const g=a.description||a.name;p.appendChild(o(g,a.required));let m;if(a.type==="select"){const l=document.createElement("select");l.className="foisit-form-input";const b=document.createElement("option");b.value="",b.textContent="Select...",l.appendChild(b);const x=h=>{(h??[]).forEach(w=>{const y=document.createElement("option");y.value=String(w.value??w.label??""),y.textContent=String(w.label??w.value??""),l.appendChild(y)})};if(Array.isArray(a.options)&&a.options.length)x(a.options);else if(typeof a.getOptions=="function"){const h=a.getOptions,w=document.createElement("option");w.value="",w.textContent="Loading...",l.appendChild(w),Promise.resolve().then(()=>h()).then(y=>{for(;l.options.length>1;)l.remove(1);x(y)}).catch(()=>{for(;l.options.length>1;)l.remove(1);const y=document.createElement("option");y.value="",y.textContent="Error loading options",l.appendChild(y)})}a.defaultValue!=null&&(l.value=String(a.defaultValue)),m=l}else if(a.type==="file"){const l=a,b=document.createElement("input");b.className="foisit-form-input",b.type="file",l.accept&&Array.isArray(l.accept)&&(b.accept=l.accept.join(",")),l.multiple&&(b.multiple=!0),l.capture&&(l.capture===!0?b.setAttribute("capture",""):b.setAttribute("capture",String(l.capture))),b.addEventListener("change",async()=>{const x=Array.from(b.files||[]),h=S;if(h.style.display="none",h.textContent="",x.length===0)return;const w=l.maxFiles??(l.multiple?10:1);if(x.length>w){h.textContent=`Please select at most ${w} file(s).`,h.style.display="block";return}const y=l.maxSizeBytes??1/0,u=x.reduce((v,E)=>v+E.size,0);if(x.some(v=>v.size>y)){h.textContent=`One or more files exceed the maximum size of ${Math.round(y/1024)} KB.`,h.style.display="block";return}const k=l.maxTotalBytes??1/0;if(u>k){h.textContent=`Total selected files exceed the maximum of ${Math.round(k/1024)} KB.`,h.style.display="block";return}if(l.accept&&Array.isArray(l.accept)){const v=l.accept;if(!x.every(L=>L.type?v.some(I=>I.startsWith(".")?L.name.toLowerCase().endsWith(I.toLowerCase()):L.type===I||L.type.startsWith(I.split("/")[0]+"/")):!0)){h.textContent="One or more files have an unsupported type.",h.style.display="block";return}}}),m=b}else{const l=document.createElement("input");l.className="foisit-form-input",a.type==="string"&&(l.placeholder=a.placeholder||"Type here..."),a.type==="number"?(l.type="number",typeof a.min=="number"&&(l.min=String(a.min)),typeof a.max=="number"&&(l.max=String(a.max)),typeof a.step=="number"&&(l.step=String(a.step)),a.defaultValue!=null&&(l.value=String(a.defaultValue))):a.type==="date"?(l.type="date",typeof a.min=="string"&&(l.min=a.min),typeof a.max=="string"&&(l.max=a.max),a.defaultValue!=null&&(l.value=String(a.defaultValue))):(l.type="text",a.defaultValue!=null&&(l.value=String(a.defaultValue))),m=l}const S=r();p.appendChild(m),p.appendChild(S),n.push({name:a.name,type:a.type,el:m,required:a.required}),s.appendChild(p)});const c=document.createElement("div");c.className="foisit-form-actions";const f=document.createElement("button");f.type="submit",f.textContent="Submit",f.className="foisit-option-chip",f.style.fontWeight="600",c.appendChild(f),s.appendChild(c),s.onsubmit=async a=>{a.preventDefault();const p={};let g=!1;s.querySelectorAll(".foisit-form-error").forEach(m=>{m.style.display="none",m.textContent=""}),s.querySelectorAll(".foisit-form-input").forEach(m=>{m.classList.remove("foisit-error-border")});for(const m of n){if(m.type==="file"){const x=m.el.parentElement,h=x==null?void 0:x.querySelector(".foisit-form-error"),w=m.el,y=Array.from(w.files||[]);if(m.required&&y.length===0){g=!0,w.classList.add("foisit-error-border"),h&&(h.textContent="This file is required",h.style.display="block");continue}if(y.length===0)continue;const u=(e??[]).find(v=>v.name===m.name),k=(u==null?void 0:u.delivery)??"file";if(u!=null&&u.maxWidth||u!=null&&u.maxHeight)try{const v=await this.getImageDimensions(y[0]);if(u.maxWidth&&v.width>u.maxWidth){g=!0,h&&(h.textContent=`Image width must be ≤ ${u.maxWidth}px`,h.style.display="block");continue}if(u.maxHeight&&v.height>u.maxHeight){g=!0,h&&(h.textContent=`Image height must be ≤ ${u.maxHeight}px`,h.style.display="block");continue}}catch{}if(u!=null&&u.maxDurationSec)try{const v=await this.getMediaDuration(y[0]);if(v&&v>u.maxDurationSec){g=!0,h&&(h.textContent=`Media duration must be ≤ ${u.maxDurationSec}s`,h.style.display="block");continue}}catch{}if(k==="file")p[m.name]=u!=null&&u.multiple?y:y[0];else if(k==="base64")try{const v=await Promise.all(y.map(E=>this.readFileAsDataURL(E)));p[m.name]=u!=null&&u.multiple?v:v[0]}catch{g=!0,h&&(h.textContent="Failed to encode file(s) to base64.",h.style.display="block");continue}continue}const S=(m.el.value??"").toString().trim(),l=m.el.parentElement,b=l==null?void 0:l.querySelector(".foisit-form-error");if(m.required&&(S==null||S==="")){g=!0,m.el.classList.add("foisit-error-border"),b&&(b.textContent="This field is required",b.style.display="block");continue}if(S!=="")if(m.type==="number"){const x=Number(S);Number.isNaN(x)||(p[m.name]=x)}else p[m.name]=S}if(g){s.classList.add("foisit-shake"),setTimeout(()=>s.classList.remove("foisit-shake"),400);return}f.disabled=!0,f.style.opacity="0.6",n.forEach(m=>{m.el.disabled=!0}),i(p)},this.messagesContainer.appendChild(s),this.scrollToBottom()}showLoading(){if(this.messagesContainer&&!this.loadingEl){this.loadingEl=document.createElement("div"),this.loadingEl.className="foisit-loading-dots foisit-bubble system";for(let t=0;t<3;t++){const e=document.createElement("div");e.className="foisit-dot",e.style.animation=`foisitPulse 1.4s infinite ease-in-out ${t*.2}s`,this.loadingEl.appendChild(e)}this.messagesContainer.appendChild(this.loadingEl),this.scrollToBottom()}}hideLoading(){var t;(t=this.loadingEl)==null||t.remove(),this.loadingEl=null}scrollToBottom(){this.messagesContainer&&(this.messagesContainer.scrollTop=this.messagesContainer.scrollHeight)}destroy(){var t;(t=this.container)==null||t.remove(),this.container=null,this.chatWindow=null,this.messagesContainer=null,this.input=null,this.isOpen=!1}readFileAsDataURL(t){return new Promise((e,i)=>{const s=new FileReader;s.onerror=()=>i(new Error("Failed to read file")),s.onload=()=>e(String(s.result)),s.readAsDataURL(t)})}getImageDimensions(t){return new Promise(e=>{try{const i=URL.createObjectURL(t),s=new Image;s.onload=()=>{const n={width:s.naturalWidth||s.width,height:s.naturalHeight||s.height};URL.revokeObjectURL(i),e(n)},s.onerror=()=>{URL.revokeObjectURL(i),e({width:0,height:0})},s.src=i}catch{e({width:0,height:0})}})}getMediaDuration(t){return new Promise(e=>{try{const i=URL.createObjectURL(t),s=t.type.startsWith("audio")?document.createElement("audio"):document.createElement("video");let n=!1;const o=setTimeout(()=>{n||(n=!0,URL.revokeObjectURL(i),e(0))},5e3);s.preload="metadata",s.onloadedmetadata=()=>{if(n)return;n=!0,clearTimeout(o);const c=s.duration||0;URL.revokeObjectURL(i),e(c)},s.onerror=()=>{n||(n=!0,clearTimeout(o),URL.revokeObjectURL(i),e(0))},s.src=i}catch{e(0)}})}injectOverlayStyles(){if(document.getElementById("foisit-overlay-styles"))return;const t=document.createElement("style");t.id="foisit-overlay-styles",t.textContent=`
34
+ `,document.head.appendChild(t),console.log("Gradient styles injected")}function D(){if(document.querySelector("#gradient-indicator"))return;const d=document.createElement("div");d.id="gradient-indicator",U(),d.classList.add("gradient-indicator"),document.body.appendChild(d),console.log("Gradient indicator added to the DOM")}function $(){const d=document.querySelector("#gradient-indicator");d&&(d.remove(),console.log("Gradient indicator removed from the DOM"))}function V(){return typeof window<"u"&&typeof document<"u"}class G{constructor(){this.state="idle",this.subscribers=[]}getState(){return this.state}setState(t){this.state=t,this.notifySubscribers(),console.log("State updated:",t),t==="listening"?D():$()}subscribe(t){this.subscribers.push(t)}notifySubscribers(){this.subscribers.forEach(t=>t(this.state))}}class Y{constructor(t){this.container=null,this.chatWindow=null,this.messagesContainer=null,this.input=null,this.isOpen=!1,this.loadingEl=null,this.active=V(),this.config=t,this.active&&this.init()}init(){var e,i;if(this.container)return;this.injectOverlayStyles();const t=document.getElementById("foisit-overlay-container");if(t&&t instanceof HTMLElement){this.container=t,this.chatWindow=t.querySelector(".foisit-chat"),this.messagesContainer=t.querySelector(".foisit-messages"),this.input=t.querySelector("input.foisit-input"),((e=this.config.floatingButton)==null?void 0:e.visible)!==!1&&!t.querySelector(".foisit-floating-btn")&&this.renderFloatingButton(),this.chatWindow||this.renderChatWindow();return}this.container=document.createElement("div"),this.container.id="foisit-overlay-container",this.container.className="foisit-overlay-container",document.body.appendChild(this.container),((i=this.config.floatingButton)==null?void 0:i.visible)!==!1&&this.renderFloatingButton(),this.renderChatWindow()}renderFloatingButton(){var s,n,o,r,c,f;const t=document.createElement("button");t.innerHTML=((s=this.config.floatingButton)==null?void 0:s.customHtml)||"🎙️";const e=((o=(n=this.config.floatingButton)==null?void 0:n.position)==null?void 0:o.bottom)||"20px",i=((c=(r=this.config.floatingButton)==null?void 0:r.position)==null?void 0:c.right)||"20px";t.className="foisit-floating-btn",t.style.bottom=e,t.style.right=i,t.onclick=()=>this.toggle(),t.onmouseenter=()=>t.style.transform="scale(1.05)",t.onmouseleave=()=>t.style.transform="scale(1)",(f=this.container)==null||f.appendChild(t)}renderChatWindow(){var n;if(this.chatWindow)return;this.chatWindow=document.createElement("div"),this.chatWindow.className="foisit-chat";const t=document.createElement("div");t.className="foisit-header";const e=document.createElement("span");e.className="foisit-title",e.textContent="Foisit";const i=document.createElement("button");i.type="button",i.className="foisit-close",i.setAttribute("aria-label","Close"),i.innerHTML="&times;",i.addEventListener("click",()=>this.toggle()),t.appendChild(e),t.appendChild(i),this.messagesContainer=document.createElement("div"),this.messagesContainer.className="foisit-messages";const s=document.createElement("div");s.className="foisit-input-area",this.input=document.createElement("input"),this.input.placeholder=this.config.inputPlaceholder||"Type a command...",this.input.className="foisit-input",this.input.addEventListener("keydown",o=>{var r;if(o.key==="Enter"&&((r=this.input)!=null&&r.value.trim())){const c=this.input.value.trim();this.input.value="",this.onSubmit&&this.onSubmit(c)}}),s.appendChild(this.input),this.chatWindow.appendChild(t),this.chatWindow.appendChild(this.messagesContainer),this.chatWindow.appendChild(s),(n=this.container)==null||n.appendChild(this.chatWindow)}registerCallbacks(t,e){this.active&&(this.onSubmit=t,this.onClose=e)}toggle(t,e){this.active&&(t&&(this.onSubmit=t),e&&(this.onClose=e),this.isOpen=!this.isOpen,this.chatWindow&&(this.isOpen?(this.chatWindow.style.display="flex",requestAnimationFrame(()=>{this.chatWindow&&(this.chatWindow.style.opacity="1",this.chatWindow.style.transform="translateY(0) scale(1)")}),setTimeout(()=>{var i;return(i=this.input)==null?void 0:i.focus()},100)):(this.chatWindow.style.opacity="0",this.chatWindow.style.transform="translateY(20px) scale(0.95)",setTimeout(()=>{this.chatWindow&&!this.isOpen&&(this.chatWindow.style.display="none")},200),this.onClose&&this.onClose())))}addMessage(t,e){if(!this.messagesContainer)return;const i=document.createElement("div");i.textContent=t,i.className=e==="user"?"foisit-bubble user":"foisit-bubble system",this.messagesContainer.appendChild(i),this.scrollToBottom()}addOptions(t){if(!this.messagesContainer)return;const e=document.createElement("div");e.className="foisit-options-container",t.forEach(i=>{const s=document.createElement("button");s.textContent=i.label,s.className="foisit-option-chip",s.setAttribute("type","button"),s.setAttribute("aria-label",i.label);const n=()=>{if(i.commandId){this.onSubmit&&this.onSubmit({commandId:i.commandId});return}const o=i&&typeof i.value=="string"&&i.value.trim()?i.value:i.label;this.onSubmit&&this.onSubmit(o)};s.onclick=n,s.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),n())},e.appendChild(s)}),this.messagesContainer.appendChild(e),this.scrollToBottom()}addForm(t,e,i){if(!this.messagesContainer)return;this.addMessage(t,"system");const s=document.createElement("form");s.className="foisit-form";const n=[],o=(a,p)=>{const g=document.createElement("div");return g.className="foisit-form-label",g.innerHTML=a+(p?' <span class="foisit-req-star">*</span>':""),g},r=()=>{const a=document.createElement("div");return a.className="foisit-form-error",a.style.display="none",a};(e??[]).forEach(a=>{const p=document.createElement("div");p.className="foisit-form-group";const g=a.description||a.name;p.appendChild(o(g,a.required));let m;if(a.type==="select"){const l=document.createElement("select");l.className="foisit-form-input";const b=document.createElement("option");b.value="",b.textContent="Select...",l.appendChild(b);const x=h=>{(h??[]).forEach(w=>{const y=document.createElement("option");y.value=String(w.value??w.label??""),y.textContent=String(w.label??w.value??""),l.appendChild(y)})};if(Array.isArray(a.options)&&a.options.length)x(a.options);else if(typeof a.getOptions=="function"){const h=a.getOptions,w=document.createElement("option");w.value="",w.textContent="Loading...",l.appendChild(w),Promise.resolve().then(()=>h()).then(y=>{for(;l.options.length>1;)l.remove(1);x(y)}).catch(()=>{for(;l.options.length>1;)l.remove(1);const y=document.createElement("option");y.value="",y.textContent="Error loading options",l.appendChild(y)})}a.defaultValue!=null&&(l.value=String(a.defaultValue)),m=l}else if(a.type==="file"){const l=a,b=document.createElement("input");b.className="foisit-form-input",b.type="file",l.accept&&Array.isArray(l.accept)&&(b.accept=l.accept.join(",")),l.multiple&&(b.multiple=!0),l.capture&&(l.capture===!0?b.setAttribute("capture",""):b.setAttribute("capture",String(l.capture))),b.addEventListener("change",async()=>{const x=Array.from(b.files||[]),h=S;if(h.style.display="none",h.textContent="",x.length===0)return;const w=l.maxFiles??(l.multiple?10:1);if(x.length>w){h.textContent=`Please select at most ${w} file(s).`,h.style.display="block";return}const y=l.maxSizeBytes??1/0,u=x.reduce((v,E)=>v+E.size,0);if(x.some(v=>v.size>y)){h.textContent=`One or more files exceed the maximum size of ${Math.round(y/1024)} KB.`,h.style.display="block";return}const k=l.maxTotalBytes??1/0;if(u>k){h.textContent=`Total selected files exceed the maximum of ${Math.round(k/1024)} KB.`,h.style.display="block";return}if(l.accept&&Array.isArray(l.accept)){const v=l.accept;if(!x.every(L=>L.type?v.some(I=>I.startsWith(".")?L.name.toLowerCase().endsWith(I.toLowerCase()):L.type===I||L.type.startsWith(I.split("/")[0]+"/")):!0)){h.textContent="One or more files have an unsupported type.",h.style.display="block";return}}}),m=b}else{const l=document.createElement("input");l.className="foisit-form-input",a.type==="string"&&(l.placeholder=a.placeholder||"Type here..."),a.type==="number"?(l.type="number",typeof a.min=="number"&&(l.min=String(a.min)),typeof a.max=="number"&&(l.max=String(a.max)),typeof a.step=="number"&&(l.step=String(a.step)),a.defaultValue!=null&&(l.value=String(a.defaultValue))):a.type==="date"?(l.type="date",typeof a.min=="string"&&(l.min=a.min),typeof a.max=="string"&&(l.max=a.max),a.defaultValue!=null&&(l.value=String(a.defaultValue))):(l.type="text",a.defaultValue!=null&&(l.value=String(a.defaultValue))),m=l}const S=r();p.appendChild(m),p.appendChild(S),n.push({name:a.name,type:a.type,el:m,required:a.required}),s.appendChild(p)});const c=document.createElement("div");c.className="foisit-form-actions";const f=document.createElement("button");f.type="submit",f.textContent="Submit",f.className="foisit-option-chip",f.style.fontWeight="600",c.appendChild(f),s.appendChild(c),s.onsubmit=async a=>{a.preventDefault();const p={};let g=!1;s.querySelectorAll(".foisit-form-error").forEach(m=>{m.style.display="none",m.textContent=""}),s.querySelectorAll(".foisit-form-input").forEach(m=>{m.classList.remove("foisit-error-border")});for(const m of n){if(m.type==="file"){const x=m.el.parentElement,h=x==null?void 0:x.querySelector(".foisit-form-error"),w=m.el,y=Array.from(w.files||[]);if(m.required&&y.length===0){g=!0,w.classList.add("foisit-error-border"),h&&(h.textContent="This file is required",h.style.display="block");continue}if(y.length===0)continue;const u=(e??[]).find(v=>v.name===m.name),k=(u==null?void 0:u.delivery)??"file";if(u!=null&&u.maxWidth||u!=null&&u.maxHeight)try{const v=await this.getImageDimensions(y[0]);if(u.maxWidth&&v.width>u.maxWidth){g=!0,h&&(h.textContent=`Image width must be ≤ ${u.maxWidth}px`,h.style.display="block");continue}if(u.maxHeight&&v.height>u.maxHeight){g=!0,h&&(h.textContent=`Image height must be ≤ ${u.maxHeight}px`,h.style.display="block");continue}}catch{}if(u!=null&&u.maxDurationSec)try{const v=await this.getMediaDuration(y[0]);if(v&&v>u.maxDurationSec){g=!0,h&&(h.textContent=`Media duration must be ≤ ${u.maxDurationSec}s`,h.style.display="block");continue}}catch{}if(k==="file")p[m.name]=u!=null&&u.multiple?y:y[0];else if(k==="base64")try{const v=await Promise.all(y.map(E=>this.readFileAsDataURL(E)));p[m.name]=u!=null&&u.multiple?v:v[0]}catch{g=!0,h&&(h.textContent="Failed to encode file(s) to base64.",h.style.display="block");continue}continue}const S=(m.el.value??"").toString().trim(),l=m.el.parentElement,b=l==null?void 0:l.querySelector(".foisit-form-error");if(m.required&&(S==null||S==="")){g=!0,m.el.classList.add("foisit-error-border"),b&&(b.textContent="This field is required",b.style.display="block");continue}if(S!=="")if(m.type==="number"){const x=Number(S);Number.isNaN(x)||(p[m.name]=x)}else p[m.name]=S}if(g){s.classList.add("foisit-shake"),setTimeout(()=>s.classList.remove("foisit-shake"),400);return}f.disabled=!0,f.style.opacity="0.6",n.forEach(m=>{m.el.disabled=!0}),i(p)},this.messagesContainer.appendChild(s),this.scrollToBottom()}showLoading(){if(this.messagesContainer&&!this.loadingEl){this.loadingEl=document.createElement("div"),this.loadingEl.className="foisit-loading-dots foisit-bubble system";for(let t=0;t<3;t++){const e=document.createElement("div");e.className="foisit-dot",e.style.animation=`foisitPulse 1.4s infinite ease-in-out ${t*.2}s`,this.loadingEl.appendChild(e)}this.messagesContainer.appendChild(this.loadingEl),this.scrollToBottom()}}hideLoading(){var t;(t=this.loadingEl)==null||t.remove(),this.loadingEl=null}scrollToBottom(){this.messagesContainer&&(this.messagesContainer.scrollTop=this.messagesContainer.scrollHeight)}destroy(){var t;(t=this.container)==null||t.remove(),this.container=null,this.chatWindow=null,this.messagesContainer=null,this.input=null,this.isOpen=!1}readFileAsDataURL(t){return new Promise((e,i)=>{const s=new FileReader;s.onerror=()=>i(new Error("Failed to read file")),s.onload=()=>e(String(s.result)),s.readAsDataURL(t)})}getImageDimensions(t){return new Promise(e=>{try{const i=URL.createObjectURL(t),s=new Image;s.onload=()=>{const n={width:s.naturalWidth||s.width,height:s.naturalHeight||s.height};URL.revokeObjectURL(i),e(n)},s.onerror=()=>{URL.revokeObjectURL(i),e({width:0,height:0})},s.src=i}catch{e({width:0,height:0})}})}getMediaDuration(t){return new Promise(e=>{try{const i=URL.createObjectURL(t),s=t.type.startsWith("audio")?document.createElement("audio"):document.createElement("video");let n=!1;const o=setTimeout(()=>{n||(n=!0,URL.revokeObjectURL(i),e(0))},5e3);s.preload="metadata",s.onloadedmetadata=()=>{if(n)return;n=!0,clearTimeout(o);const c=s.duration||0;URL.revokeObjectURL(i),e(c)},s.onerror=()=>{n||(n=!0,clearTimeout(o),URL.revokeObjectURL(i),e(0))},s.src=i}catch{e(0)}})}injectOverlayStyles(){if(document.getElementById("foisit-overlay-styles"))return;const t=document.createElement("style");t.id="foisit-overlay-styles",t.textContent=`
35
35
  :root {
36
36
  /* LIGHT MODE (Default) - Smoother gradient */
37
37
  /* Changed: Softer, right-focused radial highlight to avoid a heavy white bottom */
@@ -352,4 +352,4 @@
352
352
  transition: transform 0.2s;
353
353
  }
354
354
  .foisit-floating-btn:hover { transform: scale(1.05); }
355
- `,document.head.appendChild(t)}}class H{constructor(t){this.config=t,this.isActivated=!1,this.lastProcessedInput="",this.processingLock=!1,this.defaultIntroMessage="How can I help you?",this.commandHandler=new B({enableSmartIntent:this.config.enableSmartIntent!==!1,intentEndpoint:this.config.intentEndpoint}),this.fallbackHandler=new z,this.voiceProcessor=new O,this.textToSpeech=new q,this.stateManager=new V,this.gestureHandler=new j,this.overlayManager=new G({floatingButton:this.config.floatingButton,inputPlaceholder:this.config.inputPlaceholder}),this.config.commands.forEach(e=>this.commandHandler.addCommand(e)),this.config.fallbackResponse&&this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse),this.gestureHandler.setupDoubleTapListener(()=>this.toggle()),this.overlayManager.registerCallbacks(async e=>{if(typeof e=="string"){this.overlayManager.addMessage(e,"user"),await this.handleCommand(e);return}if(e&&typeof e=="object"){const i=e,s=i.label??i.commandId??"Selection";this.overlayManager.addMessage(String(s),"user"),this.overlayManager.showLoading();const n=await this.commandHandler.executeCommand(i);this.overlayManager.hideLoading(),this.processResponse(n)}},()=>console.log("AssistantService: Overlay closed."))}startListening(){console.log("AssistantService: Voice is disabled; startListening() is a no-op.")}stopListening(){console.log("AssistantService: Voice is disabled; stopListening() is a no-op."),this.isActivated=!1}reactivate(){console.log("AssistantService: Reactivating assistant..."),this.isActivated=!1;try{this.startListening()}catch{}}async processActivation(t){var i;const e=(i=this.config.activationCommand)==null?void 0:i.toLowerCase();e&&(t===e?(console.log("AssistantService: Activation matched."),this.isActivated=!0,this.textToSpeech.speak(this.config.introMessage||this.defaultIntroMessage)):console.log("AssistantService: Activation command not recognized."))}async handleCommand(t){this.overlayManager.showLoading();let e;try{e=await this.commandHandler.executeCommand(t)}finally{this.overlayManager.hideLoading()}if(e.type==="form"&&e.fields){this.overlayManager.addForm(e.message,e.fields,async i=>{this.overlayManager.showLoading();let s;try{s=await this.commandHandler.executeCommand(i)}finally{this.overlayManager.hideLoading()}this.processResponse(s)});return}if(e.type==="error"){this.fallbackHandler.handleFallback(t),this.overlayManager.addMessage(this.fallbackHandler.getFallbackMessage(),"system");return}if((e.type==="ambiguous"||e.type==="confirm")&&e.options){e.message&&this.overlayManager.addMessage(e.message,"system"),this.overlayManager.addOptions(e.options);return}e.message&&this.overlayManager.addMessage(e.message,"system")}destroy(){this.voiceProcessor.stopListening(),this.gestureHandler.destroy(),this.overlayManager.destroy()}processResponse(t){if(t){if(t.type==="form"&&t.fields){this.overlayManager.addForm(t.message,t.fields,async e=>{this.overlayManager.showLoading();let i;try{i=await this.commandHandler.executeCommand(e)}finally{this.overlayManager.hideLoading()}this.processResponse(i)});return}if((t.type==="ambiguous"||t.type==="confirm")&&t.options){t.message&&this.overlayManager.addMessage(t.message,"system"),this.overlayManager.addOptions(t.options);return}t.message&&this.overlayManager.addMessage(t.message,"system")}}addCommand(t,e){console.log(typeof t=="string"?`AssistantService: Adding command "${t}".`:`AssistantService: Adding rich command "${t.command}".`),this.commandHandler.addCommand(t,e)}removeCommand(t){console.log(`AssistantService: Removing command "${t}".`),this.commandHandler.removeCommand(t)}getCommands(){return this.commandHandler.getCommands()}toggle(t,e){console.log("AssistantService: Toggling overlay..."),this.overlayManager.toggle(async i=>{if(typeof i=="string"){this.overlayManager.addMessage(i,"user"),t&&t(i),await this.handleCommand(i);return}if(i&&typeof i=="object"){const s=i,n=s.label??s.commandId??"Selection";this.overlayManager.addMessage(String(n),"user"),this.overlayManager.showLoading();let o;try{o=await this.commandHandler.executeCommand(s)}finally{this.overlayManager.hideLoading()}this.processResponse(o)}},()=>{console.log("AssistantService: Overlay closed."),e&&e()})}}const M=C.createContext(null);let R=null;const Y=({config:d,children:t})=>{const[e,i]=C.useState(null),[s,n]=C.useState(!1);return C.useEffect(()=>{R?console.warn("Multiple AssistantProvider instances detected. Reusing global AssistantService."):(console.log("Initializing global AssistantService..."),R=new H(d));const o=R;return i(o),n(!0),()=>{var r;console.log("Cleaning up AssistantService..."),(r=o.destroy)==null||r.call(o),R=null}},[d]),!s||!e?A.jsx("div",{children:"Loading Assistant..."}):A.jsx(M.Provider,{value:e,children:t})},F=()=>{const d=C.useContext(M);if(console.log("assistant",d),!d)throw new Error("useAssistant must be used within an AssistantProvider");return d},K=({label:d="Activate Assistant",onActivate:t})=>{const e=F(),i=()=>{t&&t(),e.reactivate()};return A.jsx("button",{onClick:i,className:"assistant-activator",children:d})},X=d=>{const[t,e]=C.useState(d.getState());return C.useEffect(()=>{const i=s=>{e(s)};return d.subscribe(i),()=>{d.subscribe(()=>{})}},[d]),t};exports.AssistantActivator=K;exports.AssistantContext=M;exports.AssistantProvider=Y;exports.AssistantService=H;exports.ReactWrapper=W;exports.useAssistant=F;exports.useAssistantState=X;
355
+ `,document.head.appendChild(t)}}class q{constructor(t){this.config=t,this.isActivated=!1,this.lastProcessedInput="",this.processingLock=!1,this.defaultIntroMessage="How can I help you?",this.commandHandler=new B({enableSmartIntent:this.config.enableSmartIntent!==!1,intentEndpoint:this.config.intentEndpoint}),this.fallbackHandler=new z,typeof window<"u"&&typeof document<"u"?(this.voiceProcessor=new O,this.textToSpeech=new H,this.stateManager=new G,this.gestureHandler=new j,this.overlayManager=new Y({floatingButton:this.config.floatingButton,inputPlaceholder:this.config.inputPlaceholder}),this.config.commands.forEach(e=>this.commandHandler.addCommand(e)),this.config.fallbackResponse&&this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse),this.gestureHandler.setupDoubleTapListener(()=>this.toggle()),this.overlayManager.registerCallbacks(async e=>{if(typeof e=="string"){this.overlayManager.addMessage(e,"user"),await this.handleCommand(e);return}if(e&&typeof e=="object"){const i=e,s=i.label??i.commandId??"Selection";this.overlayManager.addMessage(String(s),"user"),this.overlayManager.showLoading();const n=await this.commandHandler.executeCommand(i);this.overlayManager.hideLoading(),this.processResponse(n)}},()=>console.log("AssistantService: Overlay closed."))):(this.voiceProcessor=void 0,this.textToSpeech=void 0,this.stateManager=void 0,this.gestureHandler=void 0,this.overlayManager=void 0,this.config.commands.forEach(e=>this.commandHandler.addCommand(e)),this.config.fallbackResponse&&this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse))}startListening(){if(typeof window>"u"||!this.voiceProcessor){console.log("AssistantService: Voice is disabled or unavailable; startListening() is a no-op.");return}}stopListening(){if(typeof window>"u"||!this.voiceProcessor){console.log("AssistantService: Voice unavailable; stopListening() is a no-op."),this.isActivated=!1;return}this.voiceProcessor.stopListening(),this.isActivated=!1}reactivate(){console.log("AssistantService: Reactivating assistant..."),this.isActivated=!1;try{this.startListening()}catch{}}async processActivation(t){var i;const e=(i=this.config.activationCommand)==null?void 0:i.toLowerCase();e&&(t===e?(console.log("AssistantService: Activation matched."),this.isActivated=!0,this.textToSpeech.speak(this.config.introMessage||this.defaultIntroMessage)):console.log("AssistantService: Activation command not recognized."))}async handleCommand(t){this.overlayManager.showLoading();let e;try{e=await this.commandHandler.executeCommand(t)}finally{this.overlayManager.hideLoading()}if(e.type==="form"&&e.fields){this.overlayManager.addForm(e.message,e.fields,async i=>{this.overlayManager.showLoading();let s;try{s=await this.commandHandler.executeCommand(i)}finally{this.overlayManager.hideLoading()}this.processResponse(s)});return}if(e.type==="error"){this.fallbackHandler.handleFallback(t),this.overlayManager.addMessage(this.fallbackHandler.getFallbackMessage(),"system");return}if((e.type==="ambiguous"||e.type==="confirm")&&e.options){e.message&&this.overlayManager.addMessage(e.message,"system"),this.overlayManager.addOptions(e.options);return}e.message&&this.overlayManager.addMessage(e.message,"system")}destroy(){this.voiceProcessor.stopListening(),this.gestureHandler.destroy(),this.overlayManager.destroy()}processResponse(t){if(t){if(t.type==="form"&&t.fields){this.overlayManager.addForm(t.message,t.fields,async e=>{this.overlayManager.showLoading();let i;try{i=await this.commandHandler.executeCommand(e)}finally{this.overlayManager.hideLoading()}this.processResponse(i)});return}if((t.type==="ambiguous"||t.type==="confirm")&&t.options){t.message&&this.overlayManager.addMessage(t.message,"system"),this.overlayManager.addOptions(t.options);return}t.message&&this.overlayManager.addMessage(t.message,"system")}}addCommand(t,e){console.log(typeof t=="string"?`AssistantService: Adding command "${t}".`:`AssistantService: Adding rich command "${t.command}".`),this.commandHandler.addCommand(t,e)}removeCommand(t){console.log(`AssistantService: Removing command "${t}".`),this.commandHandler.removeCommand(t)}getCommands(){return this.commandHandler.getCommands()}toggle(t,e){console.log("AssistantService: Toggling overlay..."),this.overlayManager.toggle(async i=>{if(typeof i=="string"){this.overlayManager.addMessage(i,"user"),t&&t(i),await this.handleCommand(i);return}if(i&&typeof i=="object"){const s=i,n=s.label??s.commandId??"Selection";this.overlayManager.addMessage(String(n),"user"),this.overlayManager.showLoading();let o;try{o=await this.commandHandler.executeCommand(s)}finally{this.overlayManager.hideLoading()}this.processResponse(o)}},()=>{console.log("AssistantService: Overlay closed."),e&&e()})}}const M=C.createContext(null);let R=null;const K=({config:d,children:t})=>{const[e,i]=C.useState(null),[s,n]=C.useState(!1);return C.useEffect(()=>{R?console.warn("Multiple AssistantProvider instances detected. Reusing global AssistantService."):(console.log("Initializing global AssistantService..."),R=new q(d));const o=R;return i(o),n(!0),()=>{var r;console.log("Cleaning up AssistantService..."),(r=o.destroy)==null||r.call(o),R=null}},[d]),!s||!e?A.jsx("div",{children:"Loading Assistant..."}):A.jsx(M.Provider,{value:e,children:t})},F=()=>{const d=C.useContext(M);if(console.log("assistant",d),!d)throw new Error("useAssistant must be used within an AssistantProvider");return d},X=({label:d="Activate Assistant",onActivate:t})=>{const e=F(),i=()=>{t&&t(),e.reactivate()};return A.jsx("button",{onClick:i,className:"assistant-activator",children:d})},_=d=>{const[t,e]=C.useState(d.getState());return C.useEffect(()=>{const i=s=>{e(s)};return d.subscribe(i),()=>{d.subscribe(()=>{})}},[d]),t};exports.AssistantActivator=X;exports.AssistantContext=M;exports.AssistantProvider=K;exports.AssistantService=q;exports.ReactWrapper=W;exports.useAssistant=F;exports.useAssistantState=_;
package/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx as k } from "react/jsx-runtime";
2
2
  import { createContext as F, useState as R, useEffect as P, useContext as N } from "react";
3
3
  const W = {};
4
- function Q() {
4
+ function J() {
5
5
  return /* @__PURE__ */ k("div", { className: W.container, children: /* @__PURE__ */ k("h1", { children: "Welcome to ReactWrapper!" }) });
6
6
  }
7
7
  class M {
@@ -103,7 +103,7 @@ class B {
103
103
  const c = this.getCommandById(o);
104
104
  return c ? this.safeRunAction(c, r) : { message: "That action is no longer available.", type: "error" };
105
105
  }
106
- return ["no", "n", "cancel", "stop"].includes(n) ? (this.pendingConfirmation = null, { message: "Cancelled.", type: "success" }) : {
106
+ return ["no", "n", "cancel", "stop"].includes(n) ? (this.pendingConfirmation = null, { message: "Cancelled.", type: "success" }) : {
107
107
  message: "Please confirm: Yes or No.",
108
108
  type: "confirm",
109
109
  options: [
@@ -242,7 +242,7 @@ class B {
242
242
  }
243
243
  buildConfirmResponse(t) {
244
244
  return {
245
- message: `⚠️ Are you sure you want to run "${t.command}"?`,
245
+ message: `Are you sure you want to run "${t.command}"?`,
246
246
  type: "confirm",
247
247
  options: [
248
248
  { label: "Yes", value: "yes" },
@@ -345,21 +345,21 @@ class B {
345
345
  return Array.from(this.commands.keys());
346
346
  }
347
347
  }
348
- class q {
348
+ class H {
349
349
  constructor() {
350
- this.synth = window.speechSynthesis;
350
+ this.synth = typeof window < "u" ? window.speechSynthesis : null;
351
351
  }
352
352
  speak(t, e) {
353
353
  if (!this.synth) {
354
- console.error("SpeechSynthesis API is not supported in this browser.");
354
+ console.error("SpeechSynthesis API is not supported in this environment.");
355
355
  return;
356
356
  }
357
357
  const i = new SpeechSynthesisUtterance(t);
358
- e && (i.pitch = e.pitch || 1, i.rate = e.rate || 1, i.volume = e.volume || 1), i.onstart = () => {
358
+ e && (i.pitch = e.pitch || 1, i.rate = e.rate || 1, i.volume = e.volume || 1), typeof window < "u" && (i.onstart = () => {
359
359
  window.dispatchEvent(new CustomEvent("foisit:tts-start"));
360
360
  }, i.onend = () => {
361
361
  console.log("Speech finished."), window.dispatchEvent(new CustomEvent("foisit:tts-end"));
362
- }, i.onerror = (s) => {
362
+ }), i.onerror = (s) => {
363
363
  console.error("Error during speech synthesis:", s.error);
364
364
  }, this.synth.speak(i);
365
365
  }
@@ -375,13 +375,14 @@ class z {
375
375
  this.fallbackMessage = t;
376
376
  }
377
377
  handleFallback(t) {
378
- t && console.log(`Fallback triggered for: "${t}"`), console.log(this.fallbackMessage), new q().speak(this.fallbackMessage);
378
+ t && console.log(`Fallback triggered for: "${t}"`), console.log(this.fallbackMessage), new H().speak(this.fallbackMessage);
379
379
  }
380
380
  getFallbackMessage() {
381
381
  return this.fallbackMessage;
382
382
  }
383
383
  }
384
384
  const T = () => {
385
+ if (typeof window > "u") return null;
385
386
  const d = window;
386
387
  return d.SpeechRecognition ?? d.webkitSpeechRecognition ?? null;
387
388
  };
@@ -407,16 +408,16 @@ class O {
407
408
  s.onaudiostart = () => this.log("onaudiostart"), s.onsoundstart = () => this.log("onsoundstart"), s.onspeechstart = () => this.log("onspeechstart"), s.onspeechend = () => this.log("onspeechend"), s.onsoundend = () => this.log("onsoundend"), s.onaudioend = () => this.log("onaudioend"), this.recognition.onerror = (n) => this.handleError(n);
408
409
  } else
409
410
  this.recognition = null, this.emitStatus("unsupported");
410
- window.addEventListener("foisit:tts-start", this.onTTSStart), window.addEventListener("foisit:tts-end", this.onTTSEnd), this.visibilityHandler = () => {
411
+ typeof window < "u" ? (window.addEventListener("foisit:tts-start", this.onTTSStart), window.addEventListener("foisit:tts-end", this.onTTSEnd), this.visibilityHandler = () => {
411
412
  var s;
412
- if (document.hidden) {
413
+ if (typeof document < "u" && document.hidden) {
413
414
  try {
414
415
  (s = this.recognition) == null || s.stop();
415
416
  } catch {
416
417
  }
417
418
  this.emitStatus(this.ttsSpeaking ? "speaking" : "idle");
418
419
  } else this.isListening && !this.ttsSpeaking && this.safeRestart();
419
- }, document.addEventListener("visibilitychange", this.visibilityHandler);
420
+ }, typeof document < "u" && document.addEventListener("visibilitychange", this.visibilityHandler)) : this.visibilityHandler = void 0;
420
421
  }
421
422
  // Debug logger helpers
422
423
  log(t) {
@@ -622,7 +623,10 @@ function j() {
622
623
  const d = document.querySelector("#gradient-indicator");
623
624
  d && (d.remove(), console.log("Gradient indicator removed from the DOM"));
624
625
  }
625
- class V {
626
+ function V() {
627
+ return typeof window < "u" && typeof document < "u";
628
+ }
629
+ class G {
626
630
  constructor() {
627
631
  this.state = "idle", this.subscribers = [];
628
632
  }
@@ -640,9 +644,9 @@ class V {
640
644
  this.subscribers.forEach((t) => t(this.state));
641
645
  }
642
646
  }
643
- class G {
647
+ class Y {
644
648
  constructor(t) {
645
- this.container = null, this.chatWindow = null, this.messagesContainer = null, this.input = null, this.isOpen = !1, this.loadingEl = null, this.config = t, this.init();
649
+ this.container = null, this.chatWindow = null, this.messagesContainer = null, this.input = null, this.isOpen = !1, this.loadingEl = null, this.active = V(), this.config = t, this.active && this.init();
646
650
  }
647
651
  init() {
648
652
  var e, i;
@@ -682,17 +686,17 @@ class G {
682
686
  }), s.appendChild(this.input), this.chatWindow.appendChild(t), this.chatWindow.appendChild(this.messagesContainer), this.chatWindow.appendChild(s), (n = this.container) == null || n.appendChild(this.chatWindow);
683
687
  }
684
688
  registerCallbacks(t, e) {
685
- this.onSubmit = t, this.onClose = e;
689
+ this.active && (this.onSubmit = t, this.onClose = e);
686
690
  }
687
691
  toggle(t, e) {
688
- t && (this.onSubmit = t), e && (this.onClose = e), this.isOpen = !this.isOpen, this.chatWindow && (this.isOpen ? (this.chatWindow.style.display = "flex", requestAnimationFrame(() => {
692
+ this.active && (t && (this.onSubmit = t), e && (this.onClose = e), this.isOpen = !this.isOpen, this.chatWindow && (this.isOpen ? (this.chatWindow.style.display = "flex", requestAnimationFrame(() => {
689
693
  this.chatWindow && (this.chatWindow.style.opacity = "1", this.chatWindow.style.transform = "translateY(0) scale(1)");
690
694
  }), setTimeout(() => {
691
695
  var i;
692
696
  return (i = this.input) == null ? void 0 : i.focus();
693
697
  }, 100)) : (this.chatWindow.style.opacity = "0", this.chatWindow.style.transform = "translateY(20px) scale(0.95)", setTimeout(() => {
694
698
  this.chatWindow && !this.isOpen && (this.chatWindow.style.display = "none");
695
- }, 200), this.onClose && this.onClose()));
699
+ }, 200), this.onClose && this.onClose())));
696
700
  }
697
701
  addMessage(t, e) {
698
702
  if (!this.messagesContainer) return;
@@ -741,19 +745,19 @@ class G {
741
745
  l.className = "foisit-form-input";
742
746
  const b = document.createElement("option");
743
747
  b.value = "", b.textContent = "Select...", l.appendChild(b);
744
- const x = (h) => {
745
- (h ?? []).forEach((w) => {
748
+ const w = (h) => {
749
+ (h ?? []).forEach((x) => {
746
750
  const y = document.createElement("option");
747
- y.value = String(w.value ?? w.label ?? ""), y.textContent = String(w.label ?? w.value ?? ""), l.appendChild(y);
751
+ y.value = String(x.value ?? x.label ?? ""), y.textContent = String(x.label ?? x.value ?? ""), l.appendChild(y);
748
752
  });
749
753
  };
750
754
  if (Array.isArray(a.options) && a.options.length)
751
- x(a.options);
755
+ w(a.options);
752
756
  else if (typeof a.getOptions == "function") {
753
- const h = a.getOptions, w = document.createElement("option");
754
- w.value = "", w.textContent = "Loading...", l.appendChild(w), Promise.resolve().then(() => h()).then((y) => {
757
+ const h = a.getOptions, x = document.createElement("option");
758
+ x.value = "", x.textContent = "Loading...", l.appendChild(x), Promise.resolve().then(() => h()).then((y) => {
755
759
  for (; l.options.length > 1; ) l.remove(1);
756
- x(y);
760
+ w(y);
757
761
  }).catch(() => {
758
762
  for (; l.options.length > 1; ) l.remove(1);
759
763
  const y = document.createElement("option");
@@ -764,15 +768,15 @@ class G {
764
768
  } else if (a.type === "file") {
765
769
  const l = a, b = document.createElement("input");
766
770
  b.className = "foisit-form-input", b.type = "file", l.accept && Array.isArray(l.accept) && (b.accept = l.accept.join(",")), l.multiple && (b.multiple = !0), l.capture && (l.capture === !0 ? b.setAttribute("capture", "") : b.setAttribute("capture", String(l.capture))), b.addEventListener("change", async () => {
767
- const x = Array.from(b.files || []), h = C;
768
- if (h.style.display = "none", h.textContent = "", x.length === 0) return;
769
- const w = l.maxFiles ?? (l.multiple ? 10 : 1);
770
- if (x.length > w) {
771
- h.textContent = `Please select at most ${w} file(s).`, h.style.display = "block";
771
+ const w = Array.from(b.files || []), h = C;
772
+ if (h.style.display = "none", h.textContent = "", w.length === 0) return;
773
+ const x = l.maxFiles ?? (l.multiple ? 10 : 1);
774
+ if (w.length > x) {
775
+ h.textContent = `Please select at most ${x} file(s).`, h.style.display = "block";
772
776
  return;
773
777
  }
774
- const y = l.maxSizeBytes ?? 1 / 0, u = x.reduce((v, A) => v + A.size, 0);
775
- if (x.some((v) => v.size > y)) {
778
+ const y = l.maxSizeBytes ?? 1 / 0, u = w.reduce((v, A) => v + A.size, 0);
779
+ if (w.some((v) => v.size > y)) {
776
780
  h.textContent = `One or more files exceed the maximum size of ${Math.round(y / 1024)} KB.`, h.style.display = "block";
777
781
  return;
778
782
  }
@@ -783,7 +787,7 @@ class G {
783
787
  }
784
788
  if (l.accept && Array.isArray(l.accept)) {
785
789
  const v = l.accept;
786
- if (!x.every((E) => E.type ? v.some((L) => L.startsWith(".") ? E.name.toLowerCase().endsWith(L.toLowerCase()) : E.type === L || E.type.startsWith(L.split("/")[0] + "/")) : !0)) {
790
+ if (!w.every((E) => E.type ? v.some((L) => L.startsWith(".") ? E.name.toLowerCase().endsWith(L.toLowerCase()) : E.type === L || E.type.startsWith(L.split("/")[0] + "/")) : !0)) {
787
791
  h.textContent = "One or more files have an unsupported type.", h.style.display = "block";
788
792
  return;
789
793
  }
@@ -815,9 +819,9 @@ class G {
815
819
  });
816
820
  for (const m of n) {
817
821
  if (m.type === "file") {
818
- const x = m.el.parentElement, h = x == null ? void 0 : x.querySelector(".foisit-form-error"), w = m.el, y = Array.from(w.files || []);
822
+ const w = m.el.parentElement, h = w == null ? void 0 : w.querySelector(".foisit-form-error"), x = m.el, y = Array.from(x.files || []);
819
823
  if (m.required && y.length === 0) {
820
- g = !0, w.classList.add("foisit-error-border"), h && (h.textContent = "This file is required", h.style.display = "block");
824
+ g = !0, x.classList.add("foisit-error-border"), h && (h.textContent = "This file is required", h.style.display = "block");
821
825
  continue;
822
826
  }
823
827
  if (y.length === 0) continue;
@@ -863,8 +867,8 @@ class G {
863
867
  }
864
868
  if (C !== "")
865
869
  if (m.type === "number") {
866
- const x = Number(C);
867
- Number.isNaN(x) || (p[m.name] = x);
870
+ const w = Number(C);
871
+ Number.isNaN(w) || (p[m.name] = w);
868
872
  } else
869
873
  p[m.name] = C;
870
874
  }
@@ -1267,12 +1271,12 @@ class G {
1267
1271
  `, document.head.appendChild(t);
1268
1272
  }
1269
1273
  }
1270
- class Y {
1274
+ class K {
1271
1275
  constructor(t) {
1272
1276
  this.config = t, this.isActivated = !1, this.lastProcessedInput = "", this.processingLock = !1, this.defaultIntroMessage = "How can I help you?", this.commandHandler = new B({
1273
1277
  enableSmartIntent: this.config.enableSmartIntent !== !1,
1274
1278
  intentEndpoint: this.config.intentEndpoint
1275
- }), this.fallbackHandler = new z(), this.voiceProcessor = new O(), this.textToSpeech = new q(), this.stateManager = new V(), this.gestureHandler = new U(), this.overlayManager = new G({
1279
+ }), this.fallbackHandler = new z(), typeof window < "u" && typeof document < "u" ? (this.voiceProcessor = new O(), this.textToSpeech = new H(), this.stateManager = new G(), this.gestureHandler = new U(), this.overlayManager = new Y({
1276
1280
  floatingButton: this.config.floatingButton,
1277
1281
  inputPlaceholder: this.config.inputPlaceholder
1278
1282
  }), this.config.commands.forEach((e) => this.commandHandler.addCommand(e)), this.config.fallbackResponse && this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse), this.gestureHandler.setupDoubleTapListener(() => this.toggle()), this.overlayManager.registerCallbacks(
@@ -1289,15 +1293,22 @@ class Y {
1289
1293
  }
1290
1294
  },
1291
1295
  () => console.log("AssistantService: Overlay closed.")
1292
- );
1296
+ )) : (this.voiceProcessor = void 0, this.textToSpeech = void 0, this.stateManager = void 0, this.gestureHandler = void 0, this.overlayManager = void 0, this.config.commands.forEach((e) => this.commandHandler.addCommand(e)), this.config.fallbackResponse && this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse));
1293
1297
  }
1294
1298
  /** Start listening for activation and commands */
1295
1299
  startListening() {
1296
- console.log("AssistantService: Voice is disabled; startListening() is a no-op.");
1300
+ if (typeof window > "u" || !this.voiceProcessor) {
1301
+ console.log("AssistantService: Voice is disabled or unavailable; startListening() is a no-op.");
1302
+ return;
1303
+ }
1297
1304
  }
1298
1305
  /** Stop listening */
1299
1306
  stopListening() {
1300
- console.log("AssistantService: Voice is disabled; stopListening() is a no-op."), this.isActivated = !1;
1307
+ if (typeof window > "u" || !this.voiceProcessor) {
1308
+ console.log("AssistantService: Voice unavailable; stopListening() is a no-op."), this.isActivated = !1;
1309
+ return;
1310
+ }
1311
+ this.voiceProcessor.stopListening(), this.isActivated = !1;
1301
1312
  }
1302
1313
  /**
1303
1314
  * Reset activation state so the next activation flow can occur.
@@ -1425,34 +1436,34 @@ class Y {
1425
1436
  );
1426
1437
  }
1427
1438
  }
1428
- const H = F(null);
1439
+ const q = F(null);
1429
1440
  let I = null;
1430
- const J = ({ config: d, children: t }) => {
1441
+ const Z = ({ config: d, children: t }) => {
1431
1442
  const [e, i] = R(null), [s, n] = R(!1);
1432
1443
  return P(() => {
1433
1444
  I ? console.warn(
1434
1445
  "Multiple AssistantProvider instances detected. Reusing global AssistantService."
1435
- ) : (console.log("Initializing global AssistantService..."), I = new Y(d));
1446
+ ) : (console.log("Initializing global AssistantService..."), I = new K(d));
1436
1447
  const o = I;
1437
1448
  return i(o), n(!0), () => {
1438
1449
  var r;
1439
1450
  console.log("Cleaning up AssistantService..."), (r = o.destroy) == null || r.call(o), I = null;
1440
1451
  };
1441
- }, [d]), !s || !e ? /* @__PURE__ */ k("div", { children: "Loading Assistant..." }) : /* @__PURE__ */ k(H.Provider, { value: e, children: t });
1442
- }, K = () => {
1443
- const d = N(H);
1452
+ }, [d]), !s || !e ? /* @__PURE__ */ k("div", { children: "Loading Assistant..." }) : /* @__PURE__ */ k(q.Provider, { value: e, children: t });
1453
+ }, X = () => {
1454
+ const d = N(q);
1444
1455
  if (console.log("assistant", d), !d)
1445
1456
  throw new Error("useAssistant must be used within an AssistantProvider");
1446
1457
  return d;
1447
- }, Z = ({
1458
+ }, tt = ({
1448
1459
  label: d = "Activate Assistant",
1449
1460
  onActivate: t
1450
1461
  }) => {
1451
- const e = K();
1462
+ const e = X();
1452
1463
  return /* @__PURE__ */ k("button", { onClick: () => {
1453
1464
  t && t(), e.reactivate();
1454
1465
  }, className: "assistant-activator", children: d });
1455
- }, tt = (d) => {
1466
+ }, et = (d) => {
1456
1467
  const [t, e] = R(d.getState());
1457
1468
  return P(() => {
1458
1469
  const i = (s) => {
@@ -1465,11 +1476,11 @@ const J = ({ config: d, children: t }) => {
1465
1476
  }, [d]), t;
1466
1477
  };
1467
1478
  export {
1468
- Z as AssistantActivator,
1469
- H as AssistantContext,
1470
- J as AssistantProvider,
1471
- Y as AssistantService,
1472
- Q as ReactWrapper,
1473
- K as useAssistant,
1474
- tt as useAssistantState
1479
+ tt as AssistantActivator,
1480
+ q as AssistantContext,
1481
+ Z as AssistantProvider,
1482
+ K as AssistantService,
1483
+ J as ReactWrapper,
1484
+ X as useAssistant,
1485
+ et as useAssistantState
1475
1486
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foisit/react-wrapper",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "main": "./index.js",
5
5
  "types": "./index.d.ts",
6
6
  "exports": {
@@ -19,7 +19,20 @@
19
19
  "README.md"
20
20
  ],
21
21
  "sideEffects": false,
22
- "description": "Foisit: Speak, and its done. A voice assistant library for react apps",
22
+ "description": "A powerful AI assistant library for React applications, providing seamless chatbot functionality and intelligent interactions for websites.",
23
+ "keywords": [
24
+ "ai-assistant",
25
+ "chatbot",
26
+ "react",
27
+ "ai",
28
+ "assistant",
29
+ "accessibility",
30
+ "website-integration"
31
+ ],
32
+ "homepage": "https://github.com/boluwatifee4/foisit#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/boluwatifee4/foisit/issues"
35
+ },
23
36
  "repository": {
24
37
  "type": "git",
25
38
  "url": "git+https://github.com/boluwatifee4/foisit.git"