Current File : /home/kelaby89/cartel.express/wp-content/plugins/ai-engine/app/index.js |
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./app/i18n.js":
/*!*********************!*\
!*** ./app/i18n.js ***!
\*********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
// https://developer.wordpress.org/block-editor/how-to-guides/internationalization/
const { __ } = wp.i18n;
const i18n = {};
i18n.COMMON = {
GENERAL: __( 'General', 'ai-engine' ),
MODULES: __( 'Modules', 'ai-engine' ),
CLIENT_MODULES: __( 'Client Modules', 'ai-engine' ),
BACKEND_MODULES: __( 'Admin Modules', 'ai-engine' ),
SERVER_MODULES: __( 'Server Modules', 'ai-engine' ),
ADVISOR: __( 'Advisor', 'ai-engine' ),
SETTINGS: __( 'Settings', 'ai-engine' ),
CHATBOT: __( 'Chatbot', 'ai-engine' ),
CHATBOTS: __( 'Chatbots', 'ai-engine' ),
CHATBOT_HELP: __( 'Build intelligent conversational experiences with fully customizable AI-powered chatbots.', 'ai-engine' ),
INSIGHTS: __( 'Insights', 'ai-engine' ),
STYLE: __( 'Style', 'ai-engine' ),
ENABLE: __( 'Enable', 'ai-engine' ),
NAME: __( 'Name', 'ai-engine' ),
SUBMIT: __( 'Submit', 'ai-engine' ),
MODEL: __( 'Model', 'ai-engine' ),
AI_MODEL: __( 'AI Model', 'ai-engine' ),
TEMPERATURE: __( 'Temperature', 'ai-engine' ),
MAX_TOKENS: __( 'Max Tokens', 'ai-engine' ),
CONTEXT_MAX_LENGTH: __( 'Context Max Length', 'ai-engine' ),
STOP_SEQUENCE: __( 'Stop Sequence', 'ai-engine' ),
MODE: __( 'Mode', 'ai-engine' ),
CONTEXT: __( 'Context', 'ai-engine' ),
IMAGES_NUMBER: __( 'Number of Images', 'ai-engine' ),
AVATAR: __( 'Avatar', 'ai-engine' ),
AI_NAME: __( 'AI Name', 'ai-engine' ),
GUEST_NAME: __( 'Guest Name', 'ai-engine' ),
USER_NAME: __( 'User Name', 'ai-engine' ),
PLACEHOLDER: __( 'Placeholder', 'ai-engine' ),
START_SENTENCE: __( 'Start Sentence', 'ai-engine' ),
SEND: __( 'Send', 'ai-engine' ),
CLEAR: __( 'Clear', 'ai-engine' ),
CLOSE: __( 'Close', 'ai-engine' ),
VIEW: __( 'View', 'ai-engine' ),
EDIT: __( 'Edit', 'ai-engine' ),
SYSTEM_NAME: __( 'System Name', 'ai-engine' ),
ID: __( 'ID', 'ai-engine' ),
SCOPE: __( 'Scope', 'ai-engine' ),
POPUP: __( 'Popup', 'ai-engine' ),
POSITION: __( 'Position', 'ai-engine' ),
VOICE: __( 'Voice', 'ai-engine' ),
ICON: __( 'Icon', 'ai-engine' ),
ICON_TEXT: __( 'Icon Text', 'ai-engine' ),
ICON_TEXT_DELAY: __( 'Icon Text Delay', 'ai-engine' ),
FULL_SCREEN: __( 'Full Screen', 'ai-engine' ),
CASUALLY_FINE_TUNED: __( 'Casually Fine-Tuned', 'ai-engine' ),
CONTENT_AWARE: __( 'Content Aware', 'ai-engine' ),
TITLE: __( 'Title', 'ai-engine' ),
TOPIC: __( 'Topic', 'ai-engine' ),
TOPICS: __( 'Topics', 'ai-engine' ),
SPACING: __( 'Spacing', 'ai-engine' ),
BORDER_RADIUS: __( 'Border Radius', 'ai-engine' ),
FONT_SIZE: __( 'Font Size', 'ai-engine' ),
FONT_COLOR: __( 'Font Color', 'ai-engine' ),
BACK_PRIMARY_COLOR: __( 'Back Primary Color', 'ai-engine' ),
BACK_SECONDARY_COLOR: __( 'Back 2nd Color', 'ai-engine' ),
HEADER_BUTTONS_COLOR: __( 'Header Buttons Color', 'ai-engine' ),
HEADER_BACKGROUND_COLOR: __( 'Header Back Color', 'ai-engine' ),
HEADER_SUBTITLE: __( 'Header Subtitle', 'ai-engine' ),
BUBBLE_COLOR: __( 'Bubble Color', 'ai-engine' ),
BACK_USER_COLOR: __( 'Back User Color', 'ai-engine' ),
BACK_AI_COLOR: __( 'Back AI Color', 'ai-engine' ),
BACK_AI_SECONDARY_COLOR: __( 'Back AI 2nd Color', 'ai-engine' ),
AVATAR_MESSAGE_BACKGROUND_COLOR: __( 'Message Background', 'ai-engine' ),
AVATAR_MESSAGE_FONT_COLOR: __( 'Message Color', 'ai-engine' ),
POPUP_ICON: __( 'Popup Icon', 'ai-engine' ),
CUSTOM_ICON: __( 'Custom Icon (URL or Emoticon)', 'ai-engine' ),
FEATURES: __( 'Features', 'ai-engine' ),
TIMEFRAME: __( 'Timeframe', 'ai-engine' ),
ABSOLUTE: __( 'Absolute', 'ai-engine' ),
NONE: __( 'None', 'ai-engine' ),
EDITORS_ADMINS: __( 'Editors & Admins', 'ai-engine' ),
ADMINS_ONLY: __( 'Admins Only', 'ai-engine' ),
MAINTENANCE: __( 'Maintenance', 'ai-engine' ),
CREDITS: __( 'Credits', 'ai-engine' ),
TYPE: __( 'Type', 'ai-engine' ),
LIMITS: __( 'Limits', 'ai-engine' ),
USERS: __( 'Users', 'ai-engine' ),
USER: __( 'User', 'ai-engine' ),
GUESTS: __( 'Guests', 'ai-engine' ),
GUEST: __( 'Guest', 'ai-engine' ),
OPENAI: __( 'Open AI', 'ai-engine' ),
LICENSE_TAB: __( 'License', 'ai-engine' ),
FINETUNES: __( 'Finetunes', 'ai-engine' ),
MODELS: __( 'Models', 'ai-engine' ),
FILES: __( 'Files', 'ai-engine' ),
ASSISTANT: __( 'Assistant', 'ai-engine' ),
ASSISTANTS: __( 'Assistants', 'ai-engine' ),
UTILITIES: __( 'Utilities', 'ai-engine' ),
POSTS_SUGGESTIONS: __( 'AI Copilot, AI Suggestions, Magic Wands', 'ai-engine' ),
POSTS_SUGGESTIONS_HELP: __( 'Tools to brainstorm/write faster and better.', 'ai-engine' ),
GENERATORS: __( 'Generators', 'ai-engine' ),
CONTENT_GENERATOR: __( 'Content Generator', 'ai-engine' ),
CONTENT_GENERATOR_HELP: __( 'Transform ideas into polished articles with AI-powered content creation.', 'ai-engine' ),
IMAGES_GENERATOR: __( 'Images Generator', 'ai-engine' ),
IMAGES_GENERATOR_HELP: __( 'Bring your vision to life with stunning AI-generated visuals.', 'ai-engine' ),
IMAGES_GENERATOR_INTRO: __( 'Create stunning visuals with AI-powered image generation. Use detailed prompts, customize styles and resolutions, and generate multiple variations. Perfect for creative projects, marketing materials, and visual content.', 'ai-engine' ),
PLAYGROUND: __( 'Playground', 'ai-engine' ),
PLAYGROUND_HELP: __( 'Experiment with AI models and unlock endless creative possibilities.', 'ai-engine' ),
FORMS: __( 'Forms', 'ai-engine' ),
FORMS_HELP: __( 'Create dynamic, intelligent forms that adapt and respond based on user input with conditional logic.', 'ai-engine' ),
SEARCH: __( 'Search', 'ai-engine' ),
SEARCH_HELP: __( 'Override the default WordPress search with AI powered keywords or embeddings.', 'ai-engine' ),
INSIGHTS_HELP: __( 'Enable Query Logs, Usage and Limits.', 'ai-engine' ),
CLIENT_DEBUG: __( 'Client Debug', 'ai-engine' ),
CLIENT_DEBUG_HELP: __( 'Debugging information for Chatbots and Forms will be displayed in the Browser Console.', 'ai-engine' ),
SERVER_DEBUG: __( 'Server Debug', 'ai-engine' ),
SERVER_DEBUG_HELP: __( 'API calls and server events will be logged and displayed in the Logs Console.', 'ai-engine' ),
MCP_DEBUG: __( 'MCP Debug', 'ai-engine' ),
MCP_DEBUG_HELP: __( 'Debugging information from MCP will be written directly to the PHP error logs using error_log().', 'ai-engine' ),
QUERIES_DEBUG: __( 'Queries Debug', 'ai-engine' ),
QUERIES_DEBUG_HELP: __( 'Full queries and responses will be written directly to the PHP error logs using error_log().', 'ai-engine' ),
DEV_MODE: __( 'Dev Mode', 'ai-engine' ),
DEV_MODE_HELP: __( 'Run tasks frequently for debugging.', 'ai-engine' ),
CLEAR_LOGS: __( 'Clear Logs', 'ai-engine' ),
REFRESH_LOGS: __( 'Refresh Logs', 'ai-engine' ),
API_KEY: __( 'API Key', 'ai-engine' ),
USAGE_HELP: __( 'Estimates only. Check your AI service for actual costs. Insights module provides better accuracy.', 'ai-engine' ),
RESET_USAGE_SURE: __( 'Are you sure you want to reset the usage data?', 'ai-engine' ),
USAGE_PRO_HELP: __( 'If you would like to have better control on the amounts, add conditions or set limits to the usage of the AI, consider <a href="https://meowapps.com/ai-engine/" target="_blank">AI Engine Pro</a>.', 'ai-engine' ),
LANGUAGE: __( 'Language', 'ai-engine' ),
HIDE: __( 'Hide', 'ai-engine' ),
SHOW: __( 'Show', 'ai-engine' ),
CONTENT: __( 'Content', 'ai-engine' ),
IMAGES: __( 'Images', 'ai-engine' ),
IMAGES_AND_FILES: __( 'Images & Files', 'ai-engine' ),
EXCERPT: __( 'Excerpt', 'ai-engine' ),
GENERATE: __( 'Generate', 'ai-engine' ),
MODEL_PARAMS: __( 'Model Params', 'ai-engine' ),
CONTEXT_PARAMS: __( 'Context Params', 'ai-engine' ),
PROMPT: __( 'Prompt', 'ai-engine' ),
PROMPTS: __( 'Prompts', 'ai-engine' ),
LABEL: __( 'Label', 'ai-engine' ),
SYSTEM: __( 'System', 'ai-engine' ),
SHORTCODE: __( 'Shortcode', 'ai-engine' ),
SHORTCODES: __( 'Shortcodes', 'ai-engine' ),
RESOLVE: __( 'Resolve', 'ai-engine' ),
MAX_MESSAGES: __( 'Max Messages', 'ai-engine' ),
INPUT_MAX_LENGTH: __( 'Input Max Length', 'ai-engine' ),
COMPLIANCE_TEXT: __( 'Compliance Text', 'ai-engine' ),
MODERATION: __( 'Moderation', 'ai-engine' ),
MODERATION_HELP: __( 'Moderation features with AI.', 'ai-engine' ),
FORMATTING: __( 'Formatting', 'ai-engine' ),
FORMATTING_HELP: __( 'Format the reply from AI into HTML. This is already done automatically if Markdown is detected in the reply.', 'ai-engine' ),
LOGS: __( 'Logs', 'ai-engine' ),
QUERY: __( 'Query', 'ai-engine' ),
REPLY: __( 'Reply', 'ai-engine' ),
CODE: __( 'Code', 'ai-engine' ),
EMBEDDINGS: __( 'Embeddings', 'ai-engine' ),
QUERY_LOGS: __( 'Query Logs', 'ai-engine' ),
KNOWLEDGE: __( 'Knowledge', 'ai-engine' ),
KNOWLEDGE_HELP: __( 'Searchable data for AI. Powered by <b>embeddings</b> for now, alternatives will come later.', 'ai-engine' ),
REMOTE_ACCESS: __( 'Remote Access', 'ai-engine' ),
OTHERS: __( 'Others', 'ai-engine' ),
PINECONE_APIKEY_HELP: __( 'You can get your API Keys in your <a href="https://app.pinecone.io/organizations/keys" target="_blank">Pinecone Account</a>.', 'ai-engine' ),
QDRANT_APIKEY_HELP: __( 'You can get your API Keys in your <a href="https://cloud.qdrant.io/accounts/" target="_blank">Qdrant Account</a>.', 'ai-engine' ),
SERVER: __( 'Server', 'ai-engine' ),
PINECONE_SERVER_HELP: __( 'The URL of your host (check your Indexes).', 'ai-engine' ),
PINECONE_NAMESPACE_HELP: __( 'The namespace is used to separate the data from other data. This allows you to use the same server/index on more than one website. This is optional.', 'ai-engine' ),
QDRANT_SERVER_HELP: __( 'The URL of your cluster (known as Cluster URL).', 'ai-engine' ),
QDRANT_COLLECTION_HELP: __( 'The collection keeps data apart so you can use one cluster for many websites. If there\'s no collection, Qdrant makes one with 1536 dimensions and uses cosine similarity.', 'ai-engine' ),
COST: __( 'Cost', 'ai-engine' ),
USAGE: __( 'Usage', 'ai-engine' ),
USAGE_ESTIMATES_NOTE: __( 'Costs and tokens are estimates. For accurate data and detailed analytics, visit the Insights tab.', 'ai-engine' ),
ACTIVITY: __( 'Activity', 'ai-engine' ),
TRANSCRIPTION: __( 'Transcription', 'ai-engine' ),
TRANSCRIPTION_HELP: __( 'Introduces a \'Transcribe\' tab to easily transform audio/images into text and get AI answers in JSON format.', 'ai-engine' ),
AUDIO_TRANSCRIPTION: __( 'Audio-to-Text', 'ai-engine' ),
IMAGE_TRANSCRIPTION: __( 'Image-to-Text', 'ai-engine' ),
AUDIO_TO_TEXT: __( 'Audio ➡ Text', 'ai-engine' ),
IMAGE_TO_TEXT: __( 'Image ➡ Text', 'ai-engine' ),
EMBEDDINGS_ENV: __( 'Environment', 'ai-engine' ),
EMBEDDINGS_INDEX: __( 'Index', 'ai-engine' ),
NAMESPACE: __( 'Namespace', 'ai-engine' ),
NAMESPACES: __( 'Namespaces', 'ai-engine' ),
NAMESPACE_HELP: __( 'The namespace is used to separate the data from other data. This allows you to use the same index on more than one website.', 'ai-engine' ),
NAMESPACES_HELP: __( 'Enter the namespaces you would like to use on this site, separated by commas.', 'ai-engine' ),
ERROR: __( 'Error', 'ai-engine' ),
RETRY: __( 'Retry', 'ai-engine' ),
AUTO_RETRY: __( 'Auto Retry', 'ai-engine' ),
SKIP: __( 'Skip', 'ai-engine' ),
AUTO_SKIP: __( 'Auto Skip', 'ai-engine' ),
STOP: __( 'Stop', 'ai-engine' ),
AUTO_RETRY_DESCRIPTION: __( 'Auto Retry retries actions up to 10 times with increasing delay to avoid timeouts.', 'ai-engine' ),
WIDTH: __( 'Width', 'ai-engine' ),
MAX_HEIGHT: __( 'Max Height', 'ai-engine' ),
APPEARANCE: __( 'Appearance', 'ai-engine' ),
THRESHOLDS: __( 'Thresholds', 'ai-engine' ),
DASHBOARD: __( 'Dashboard', 'ai-engine' ),
ADVANCED: __( 'Advanced', 'ai-engine' ),
DISCUSSIONS: __( 'Discussions', 'ai-engine' ),
DISCUSSION_TITLES: __( 'Discussion Titles', 'ai-engine' ),
SUMMARIZE: __( 'Summarize', 'ai-engine' ),
ROWS: __( 'Rows', 'ai-engine' ),
POST_TYPE: __( 'Post Type', 'ai-engine' ),
GENERATE_CONTENT: __( 'Generate Content', 'ai-engine' ),
GENERATE_IMAGES: __( 'Generate Images', 'ai-engine' ),
REST_API: __( 'REST API', 'ai-engine' ),
ADMIN_BAR: __( 'Admin Bar', 'ai-engine' ),
REFRESH: __( 'Refresh', 'ai-engine' ),
DELETE: __( 'Delete', 'ai-engine' ),
DELETE_ALL: __( 'Delete All', 'ai-engine' ),
DELETE_SELECTED: __( 'Delete Selected', 'ai-engine' ),
OPENAI_ORGANIZATION_ID: __( 'Organization ID', 'ai-engine' ),
OPENAI_AZURE_API_KEY: __( 'API Key', 'ai-engine' ),
OPENAI_AZURE_DEPLOYMENT_NAME: __( 'Deployment Name', 'ai-engine' ),
OPENAI_AZURE_DEPLOYMENTS: __( 'Deployments', 'ai-engine' ),
ENDPOINT: __( 'Endpoint', 'ai-engine' ),
HUGGINGFACE_MODELS: __( 'Models', 'ai-engine' ),
HUGGINGFACE_MODEL_NAME: __( 'Name', 'ai-engine' ),
HUGGINGFACE_MODEL_URL: __( 'API URL', 'ai-engine' ),
THEME: __( 'Theme', 'ai-engine' ),
THEMES: __( 'Themes', 'ai-engine' ),
BANNED_WORDS: __( 'Banned Words', 'ai-engine' ),
WORD_BOUNDARIES: __( 'Word Boundaries', 'ai-engine' ),
IGNORE: __( 'Ignore', 'ai-engine' ),
BANNED_IPS: __( 'Banned IPs', 'ai-engine' ),
SECURITY: __( 'Security', 'ai-engine' ),
POST_TYPES: __( 'Post Types', 'ai-engine' ),
COPY_BUTTON: __( 'Copy Button', 'ai-engine' ),
AI_AVATAR: __( 'AI Avatar', 'ai-engine' ),
GUEST_AVATAR: __( 'Guest Avatar', 'ai-engine' ),
SITE_WIDE_CHATBOT: __( 'Site-Wide Chatbot', 'ai-engine' ),
QUERIES_DATA: __( 'Queries Data', 'ai-engine' ),
QUERIES_FORMS_DATA: __( 'Queries Form Data', 'ai-engine' ),
WEBSPEECH_API: __( 'Web Speech API', 'ai-engine' ),
VIRTUAL_KEYBOARD: __( 'Virtual Keyboard', 'ai-engine' ),
GDPR_CONSENT: __( 'GDPR Consent', 'ai-engine' ),
GDPR_TEXT: __( 'GDPR Text', 'ai-engine' ),
GDPR_BUTTON: __( 'GDPR Button', 'ai-engine' ),
FIX: __( 'Fix', 'ai-engine' ),
SPEECH_RECOGNITION: __( 'Speech Recognition', 'ai-engine' ),
SPEECH_SYNTHESIS: __( 'Speech Synthesis', 'ai-engine' ),
QUERIES: __( 'Queries', 'ai-engine' ),
LOCAL_MEMORY: __( 'Local Memory', 'ai-engine' ),
ACTIONS: __( 'Actions', 'ai-engine' ),
RESET: __( 'Reset', 'ai-engine' ),
INCIDENTS_OPENAI: __( 'Incidents (OpenAI)', 'ai-engine' ),
PREVIEW: __( 'Preview', 'ai-engine' ),
LEGACY_FORMS: __( 'Legacy Forms', 'ai-engine' ),
LEGACY_FEATURES: __( 'Legacy Features', 'ai-engine' ),
DUPLICATE: __( 'Duplicate', 'ai-engine' ),
CHATBOT_EDITOR: __( 'Chatbot Editor', 'ai-engine' ),
THEME_EDITOR: __( 'Theme Editor', 'ai-engine' ),
STREAMING: __( 'Streaming', 'ai-engine' ),
SYNTAX_HIGHLIGHT: __( 'Syntax Highlight', 'ai-engine' ),
EVENT_LOGS: __( 'Event Logs', 'ai-engine' ),
PRIVACY_FIRST: __( 'Privacy First', 'ai-engine' ),
DATA_NOT_AVAILABLE: __( 'Data not available.', 'ai-engine' ),
EXPORT: __( 'Export', 'ai-engine' ),
IMPORT: __( 'Import', 'ai-engine' ),
MODIFY_EMBEDDING: __( 'Modify Embedding', 'ai-engine' ),
ADD_EMBEDDING: __( 'Add Embedding', 'ai-engine' ),
DEV_TOOLS: __( 'Dev Tools', 'ai-engine' ),
SINGLE_GENERATE: __( 'Single Generate', 'ai-engine' ),
PUBLIC_API: __( 'Public API', 'ai-engine' ),
USER_INTERFACE: __( 'User Interface', 'ai-engine' ),
INTRO_MESSAGE: __( 'Intro Message', 'ai-engine' ),
ADDONS: __( 'Add-ons', 'ai-engine' ),
AI_ENVIRONMENT_DEFAULTS: __( 'Default Environments for AI', 'ai-engine' ),
ENVIRONMENTS_FOR_AI: __( 'Environments for AI', 'ai-engine' ),
ENVIRONMENT_ID: __( 'Environment ID', 'ai-engine' ),
EMBEDDINGS_ENVIRONMENT_DEFAULT: __( 'Default Embeddings Environment', 'ai-engine' ),
ENVIRONMENT: __( 'Environment', 'ai-engine' ),
PLUGIN_DATA: __( 'Plugin Data', 'ai-engine' ),
PLUGIN_DATA_DESCRIPTION: __( "The database and all the options of the plugin will be removed on uninstall.", 'ai-engine' ),
RESET_LIMITS: __( 'Reset Limits', 'ai-engine' ),
VISION: __( 'Vision', 'ai-engine' ),
FILE_SEARCH: __( 'File Search', 'ai-engine' ),
PROMPT_TO_JSON: __( 'Prompt ➡ JSON', 'ai-engine' ),
RESOLUTION: __( 'Resolution', 'ai-engine' ),
DEFAULT: __( 'Default', 'ai-engine' ),
DEFAULTS: __( 'Defaults', 'ai-engine' ),
DEFAULT_FAST: __( 'Default (Fast)', 'ai-engine' ),
REFRESH_MODELS: __( 'Refresh Models', 'ai-engine' ),
AUDIO: __( 'Audio', 'ai-engine' ),
JSON: __( 'JSON', 'ai-engine' ),
AI_ENVIRONMENT: __( 'AI Environment', 'ai-engine' ),
OVERRIDE_DEFAULTS: __( 'Override Defaults', 'ai-engine' ),
REGION: __( 'Region', 'ai-engine' ),
PROJECT_ID: __( 'Project ID', 'ai-engine' ),
BEARER_TOKEN: __( 'Bearer Token', 'ai-engine' ),
DIMENSIONS: __( 'Dimensions', 'ai-engine' ),
EMBEDDINGS_MODEL: __( 'Embeddings Model', 'ai-engine' ),
MIN_SCORE: __( 'Min Score', 'ai-engine' ),
MAX_SELECT: __( 'Max Results', 'ai-engine' ),
QDRANT_COLLECTION: __( 'Collection', 'ai-engine' ),
INSTRUCTIONS: __( 'Instructions', 'ai-engine' ),
FUNCTIONS: __( 'Functions', 'ai-engine' ),
TOOLS: __( 'Tools', 'ai-engine' ),
WEB_SEARCH: __( 'Web Search', 'ai-engine' ),
IMAGE_GENERATION: __( 'Image Generation', 'ai-engine' ),
HISTORY_STRATEGY: __( 'History Strategy', 'ai-engine' ),
AUTOMATIC: __( 'Automatic', 'ai-engine' ),
FULL_HISTORY: __( 'Full History', 'ai-engine' ),
INCREMENTAL: __( 'Incremental', 'ai-engine' ),
BUBBLE: __( 'Bubble', 'ai-engine' ),
TABS: __( 'Tabs', 'ai-engine' ),
DROPDOWN: __( 'Dropdown', 'ai-engine' ),
CHATBOT_SELECT: __( 'Chatbot Select', 'ai-engine' ),
CONDITIONS: __( 'Conditions', 'ai-engine' ),
CONDITION: __( 'Condition', 'ai-engine' ),
ADD_CONDITION: __( 'Add Condition', 'ai-engine' ),
REMOVE: __( 'Remove', 'ai-engine' ),
MCP_NO_OPTIONS: __( 'MCP is enabled but no options are selected. Please enable at least one option.', 'ai-engine' ),
ORCHESTRATION: __( 'Orchestration', 'ai-engine' ),
ORCHESTRATION_HELP: __( 'Connect AI models to external tools and services through MCP servers. Currently, MCP servers need to be set up in Settings > Orchestration.', 'ai-engine' ),
MCP_SERVERS: __( 'MCP Servers', 'ai-engine' ),
MCP_FUNCTIONS: __( 'MCP Functions', 'ai-engine' ),
URL: __( 'URL', 'ai-engine' ),
TOKEN: __( 'Token', 'ai-engine' ),
SERVER_ID: __( 'Server ID', 'ai-engine' ),
};
i18n.FORMS = {
PROMPT_INFO: __( 'The template of your prompt. To re-use the data entered by the user, use the name of that field between curly braces. Example: Recommend me {MUSIC_TYPE} artists. You can also use an ID as an input, like this: ${#myfield}. Finally, if you wish the output to be formatted, add: \'Use Markdown.\'."', 'ai-engine' ),
OUTPUT: __( 'Output', 'ai-engine' ),
OUTPUT_ELEMENT: __( 'Output Element', 'ai-engine' ),
OUTPUT_ELEMENT_INFO: __( 'The result will be written to this element. If you wish to simply display the result in an Output Block, use its ID. For instance, if its ID is mwai-666, use \'#mwai-666\'.', 'ai-engine' ),
};
i18n.HELP = {
TEMPERATURE: __( 'Between 0 and 1. Higher values means the model will take more risks.', 'ai-engine' ),
MAX_TOKENS: __( 'The maximum number of tokens to generate. The model will stop generating once it hits this limit.', 'ai-engine' ),
STOP_SEQUENCE: __( 'The sequence of tokens that will cause the model to stop generating text. You absolutely need this with fine-tuned models.', 'ai-engine' ),
COST: __( 'Keeps track of the current costs.', 'ai-engine' ),
RESOLVE_SHORTCODE: __( 'Will resolve the shortcode in your content when needed (Content-Aware will use this, for instance).', 'ai-engine' ),
FINETUNES: __( 'Train your own AI models.', 'ai-engine' ),
DISCUSSIONS: __( 'Keep the conversations and enable browsing them via the Conversations tab.', 'ai-engine' ),
DISCUSSION_TITLES: __( 'Generate titles for the discussions automatically with AI.', 'ai-engine' ),
DISCUSSION_SUMMARY: __( 'Automatically generate a brief summary of the discussion using the default (fast) model. It will be used as the discussion title.', 'ai-engine' ),
AZURE_DEPLOYMENTS: __( 'Add your deployments below and define what kind of model they are.', 'ai-engine' ),
BANNED_WORDS: __( 'Reject queries containing these words; separate with commas.', 'ai-engine' ),
WORD_BOUNDARIES: __( 'Ignore standard word separation (space) and match banned words anywhere in the text.', 'ai-engine' ),
BANNED_IPS: __( 'Block access from specified IP addresses or ranges using CIDR notation; separate with commas.', 'ai-engine' ),
VIRTUAL_KEYBOARD: __( 'Prevent the virtual keyboard from pushing the chatbot up on mobile devices. This is experimental and might cause issues.', 'ai-engine' ),
GDPR_CONSENT: __( 'If enabled, the user will have to accept the conditions before using the chatbot.', 'ai-engine' ),
POST_TYPES: __( 'Enable for these post types; separate with commas.', 'ai-engine' ),
POST_STATUS: __( 'Enable for these post statuses (publish, draft, future, private, etc); separate with commas.', 'ai-engine' ),
POST_CATEGORIES: __( 'Enable for these categories (slugs); separate with commas. If none, it will be enabled for all.', 'ai-engine' ),
CONTEXT_MAX_LENGTH: __( 'Truncate the context (Content-Aware, Embeddings, etc) to make sure it is below this number of characters.', 'ai-engine' ),
MAX_MESSAGES: __( 'Maximum number of historical messages that is sent to the AI model.', 'ai-engine' ),
INPUT_MAX_LENGTH: __( 'Maximum number of characters that can be input by the user.', 'ai-engine' ),
STATISTICS: __( ' In the Insights tab, you can browse through all your users\' activity. Contextual data is excluded unless you activate the options below. Make sure your users are aware of this.', 'ai-engine' ),
QUERIES_DATA: __( 'Record the queries and their replies.', 'ai-engine' ),
QUERIES_FORMS_DATA: __( 'Capture form data neatly for simple reuse.', 'ai-engine' ),
SPEECH_RECOGNITION: __( 'Enable speech-to-text. Depends on the browser and OS used by the user.', 'ai-engine' ),
SPEECH_SYNTHESIS: __( 'Enable text-to-speech.', 'ai-engine' ),
CUSTOM_SHORTCODE: __( 'Prefer the above version. If you need many chatbots, you can custom shortcodes, like the one below. Custom shortcodes are based on the default chatbot, and their attributes override the default ones.', 'ai-engine' ),
USER_FILTER: __( 'Type an User ID, or an IP.', 'ai-engine' ),
STREAMING: __( 'The AI\'s response will appear as it\'s being created. Be cautious: this feature\'s ability to manage statistics, limits, and filters is still in its beta phase.', 'ai-engine' ),
SYNTAX_HIGHLIGHT: __( 'Enable syntax highlighting for the code blocks.', 'ai-engine' ),
EVENT_LOGS: __( 'Display streaming events and function calls in the chatbot interface for debugging. Requires Streaming to be enabled. Currently only visible in chatbots.', 'ai-engine' ),
PRIVACY_FIRST: __( 'Only essential data is stored. IPs, conversations, and other private details are minimized and kept as anonymous as possible.', 'ai-engine' ),
DEV_TOOLS: __( 'Enable a new tab with debugging tools. For developers only.', 'ai-engine' ),
DEV_MODE: __( 'Run tasks very frequently for debugging.', 'ai-engine' ),
PUBLIC_API: __( 'Enable the Public REST API.', 'ai-engine' ),
INTRO_MESSAGE: __( 'Enable introduction messages on some modules.', 'ai-engine' ),
ADDONS: __( 'Enable the AI Addons section under the Meow Apps menu.', 'ai-engine' ),
OPENAI_API_KEY: __( 'You can get your API Keys in your <a href="https://platform.openai.com/api-keys" target="_blank">OpenAI Account</a>.', 'ai-engine' ),
OPENAI_ORGANIZATION_ID: __( 'You can link this environment to an <a href="https://platform.openai.com/account/organization" target="_blank">Organization</a>. This is optional.', 'ai-engine' ),
AZURE_API_KEY: __( 'You can get your API Keys in your <a href="https://oai.azure.com/portal" target="_blank">Azure Account</a>.', 'ai-engine' ),
ANTHROPIC_API_KEY: __( 'You can get your API Keys in your <a href="https://console.anthropic.com/settings/keys" target="_blank">Anthropic Account</a>.', 'ai-engine' ),
OPENROUTER_API_KEY: __( 'You can get your API Keys in your <a href="https://openrouter.ai/keys" target="_blank">OpenRouter Account</a>.', 'ai-engine' ),
QDRANT: __( 'Use the code <b>#AIENGINE5</b> when you <a href="https://qdrant.to/cloud" target="_blank">Create a Qdrant Account</a>. You will get 5% off.', 'ai-engine' ),
ASSISTANTS: __( 'The Assistants API is designed to help developers build powerful AI assistants capable of performing a variety of tasks.', 'ai-engine' ),
ASSISTANTS_INTRO: __( 'The Assistants API is designed to help developers build powerful AI assistants capable of performing a variety of tasks. To create them, head to the <a href="https://beta.openai.com/assistants" target="_blank">OpenAI Assistants</a> dashboard, then <b>Refresh Assistants</b> here. You can use an assistant in your chatbots by switching the <b>Mode</b> to <b>Assistant</b>.', 'ai-engine' ),
ASSISTANTS_WARNINGS: __( 'Assistants are also <a href="https://platform.openai.com/docs/api-reference/assistants" target="_blank">in beta</a>, both for OpenAI and AI Engine. OpenAI did not add streaming support for them yet. Pricing is still quite unclear and <a href="https://openai.com/pricing" target="_blank">tricky</a>. AI Engine can only perform an estimation. If you want to discuss assistants with other users, visit the <a href="https://discord.gg/bHDGh38" target="_blank">Meow Apps Discord Server</a>.', 'ai-engine' ),
BEARER_TOKEN: __( 'The Public API will be usable by using this Bearer Token. If not set, you will need to <a href="https://meowapps.com/ai-engine/api/#public-rest-api" target="_blank">build your own authentication</a> by using the <i>mwai_allow_public_api</i> filter.', 'ai-engine' ),
REST_API_INTRO: __( 'The REST API enables integration with automation platforms and external applications. Use it with <a href="https://www.make.com/en/integrations/ai-engine" target="_blank">Make.com</a>, n8n, Zapier, or any platform that supports REST APIs to automate AI workflows and connect your WordPress site with other services.', 'ai-engine' ),
MCP_BEARER_TOKEN: __( 'MCP will be usable by using this Bearer Token. If not set, you will need to build your own authentication by using the <i>mwai_allow_mcp</i> filter.', 'ai-engine' ),
MCP_INTRO: __( 'Enabling the SSE Endpoint creates a Model Context Protocol (MCP) server that provides various tools depending on the options selected below. <a href="https://meowapps.com/claude-wordpress-mcp/" target="_blank">This tutorial is highly recommended</a>. Currently, Claude works well with MCP servers but cannot handle SSE directly, so a relay is needed. The /labs/mcp.js script should be run locally next to your Claude instance.', 'ai-engine' ),
MCP_SERVER_URL: __( 'The URL of the MCP server. Must start with https://', 'ai-engine' ),
MCP_SERVER_TOKEN: __( 'Bearer token for authenticating with the MCP server.', 'ai-engine' ),
NO_EMBEDDINGS_RESULTS: __( 'No results for this search. Make sure the Minimum Score is not too high.', 'ai-engine' ),
NO_EMBEDDINGS_ROWS: __( 'No embeddings yet in this environment.', 'ai-engine' ),
MIN_SCORE: __( 'The minimum score the embeddings need to have to be returned. Between 0 and 100 and defaults to 35.', 'ai-engine' ),
MAX_SELECT: __( 'The maximum number of embeddings to return and to use as context. Between 1 and 100 and defaults to 10.', 'ai-engine' ),
FUNCTIONS: __( 'Select the functions to make available for the AI model\'s choice. It will use them to enhance responses and perform specific actions. This feature is known as Function Calling or Tools.', 'ai-engine' ),
FUNCTIONS_UNAVAILABLE: __( 'There are no functions available. Please use <a href="https://wordpress.org/plugins/code-engine/" target="_blank">Code Engine</a> to add some. The Pro Version of AI Engine is also required for this feature.', 'ai-engine' ),
MCP_SERVERS: __( 'Select the MCP servers to make available for the AI model. These servers provide external tools and capabilities that the AI can use to enhance responses and perform specialized actions.', 'ai-engine' ),
MCP_SERVERS_UNAVAILABLE: __( 'No MCP servers are available. Configure them in Settings > Orchestration.', 'ai-engine' ),
TOOLS: __( 'Enable AI tools like web search and image generation to enhance your chatbot capabilities.', 'ai-engine' ),
WEB_SEARCH: __( 'Allow the AI to search the web for current information', 'ai-engine' ),
IMAGE_GENERATION: __( 'Allow the AI to generate images based on text descriptions', 'ai-engine' ),
HISTORY_STRATEGY: __( 'Control how conversation history is sent to the Responses API. Incremental uses previous_response_id for efficiency, Full History sends all messages.', 'ai-engine' ),
ADVISOR: __( 'In your Dashboard will be displayed daily recommendations tailored to your WordPress setup. Admins only.', 'ai-engine' ),
BUBBLE: __( 'The popup will be displayed as a bubble.', 'ai-engine' ),
ICON_TEXT: __( 'If set, this text will appear next to the icon/bubble.', 'ai-engine' ),
ICON_TEXT_DELAY: __( 'The delay before the text appears.', 'ai-engine' ),
CHATBOT_SELECT: __( 'Choose how you want to select the chatbot. By default, tabs are used, but you can also use a filterable dropdown if you have many chatbots.', 'ai-engine' ),
};
i18n.SETTINGS = {
AI_ENV_SETUP: __( 'To leverage the functionalities of AI Engine, it needs to be connected directly to AI services. We recommend starting with OpenAI. Create an account and generate an API Key by visiting the <a href="https://platform.openai.com/api-keys" target="_blank">OpenAI</a> website. Once obtained, navigate to the <b>Settings</b> tab and input your OpenAI API Key in the "Environments for AI" section.', 'ai-engine' ),
PINECONE_SETUP: __( 'You choose to use Embeddings. To use them, you need to a Pinecone account. Visit the <a href="https://app.pinecone.io" target="_blank">Pinecone</a> website to create an account, then insert your Pinecone API Key in the <b>Settings</b> tab.', 'ai-engine' ),
INTRO: __( 'Boost your WordPress with AI, now! Please start with our <a href="https://meowapps.com/ai-engine/tutorial/" target="_blank">tutorial</a>. Then move to our <a href="https://ai.thehiddendocs.com/" target="_blank">documentation</a>. Have a look at our <a href="https://meowapps.com/products/category/ai-add-ons/" target="_blank">add-ons</a>. And make sure you read the <a href="https://meowapps.com/ai-engine/disclaimer/" target="_blank">disclaimer</a>. Have fun! 🎵', 'ai-engine' ),
MODULES_INTRO: __( 'To avoid cluttering the UI and your WP, only enable the features you need.', 'ai-engine' ),
ALERT_INJECT_BUT_NO_POPUP: __( 'You choose to inject the chatbot in your website. You probably also want to use the chatbot in a Popup.', 'ai-engine' ),
ALERT_CASUALLY_BUT_NO_FINETUNE: __( 'Normally, you should not check the Casually Fine Tuned option with a non-finetuned model. Make sure that\'s what you want.', 'ai-engine' ),
ALERT_CONTENTAWARE_BUT_NO_CONTENT: __( 'Content Aware requires your Context to use the {CONTENT} placeholder. It will be replaced by the content of page the chatbot is on. More info <a href="https://meowapps.com/ai-engine/tutorial/#contextualization" target="_blank">here</a>.', 'ai-engine' ),
SET_AS_DEFAULT_PARAMETERS: __( 'Set as Default Parameters', 'ai-engine' ),
SET_AS_DEFAULT_PARAMETERS_HELP: __( 'Set the parameters above as the default parameters for the chatbot. You can then use the shortcode [mwai_chat] anywhere on your website.', 'ai-engine' ),
INJECT_DEFAULT_CHATBOT: __( 'Inject Default Chatbot in Entire Website', 'ai-engine' ),
INJECT_DEFAULT_CHATBOT_HELP: __( 'Inject the chatbot [mwai_chat] in the entire website.', 'ai-engine' ),
CHATGPT_STYLE_INTRO: __( 'Keep in mind that you can also style the chatbot (or a specific chatbot, if you use many) by injecting CSS. Have a look <a target="_blank" href="https://meowapps.com/ai-engine/tutorial/#apply-custom-style-to-the-chatbot">here</a>. More information in the <a target="_blank" href="https://meowapps.com/ai-engine/faq">FAQ</a>.', 'ai-engine' ),
TYPEWRITER_EFFECT: __( 'Typewriter Effect', 'ai-engine' ),
TYPEWRITER_EFFECT_HELP: __( 'The reply from AI will be typewrited. This delays the final output! Absolutely not recommended. Please use <b>Streaming</b> instead.', 'ai-engine' ),
CHATBOT_MODERATION_HELP: __( 'If the conversation seems offensive, the chatbot will reject it.', 'ai-engine' ),
CUSTOM_URL: __( 'Custom URL', 'ai-engine' ),
ASSISTANT_NO_FILE_SEARCH: __( 'This assistant does not support File Search. You can activate it on the <a href="https://platform.openai.com/assistants" target="_blank">OpenAI Assistants</a> dashboard. Then, use the Refresh button in the Assistants tab.', 'ai-engine' ),
ASSISTANT_FILE_SEARCH: __( 'File Search will be used when the users upload documents. If the user uploads images, those will be handled by AI Vision if the model supports it and if it is enabled.', 'ai-engine' ),
MCP_SERVERS_INFO: __( 'MCP (Model Context Protocol) servers enable AI models to interact with external tools and systems. The URL must be a secure HTTPS endpoint that implements the MCP protocol. You can configure multiple servers to provide different capabilities to your AI models.', 'ai-engine' ),
REMOTE_ACCESS_INFO: __( 'AI Engine provides two ways to integrate with external systems: REST API and Model Context Protocol (MCP).<h2>REST API</h2><p>Ideal for automation platforms like Make.com, Zapier, or n8n. Use this when you want to trigger AI operations from external services or integrate AI Engine into your existing workflows.</p><h2>MCP</h2><p><u>How to Use</u></p><ul><li>- <b>Claude Desktop App:</b> Use the <code>mcp.js</code> relay. Check <code>/labs/mcp.md</code> for setup instructions.</li><li>- <b>OpenAI/ChatGPT:</b> Limited to Deep Research mode with only <code>search</code> and <code>fetch</code> tools (requires Tuned Core enabled).</li><li>- <b>Claude.ai:</b> Currently not supported.</li></ul><p><u>Available Tools</u></p><ul><li>- <b>Full access (Claude Desktop):</b> WordPress management, plugin/theme development, SEO Engine, Code Engine snippets</li><li>- <b>Limited access (OpenAI):</b> Only search and fetch WordPress posts/pages</li></ul><p><u>For Developers</u></p><p>Extend functionality using <code>mwai_mcp_tools</code> and <code>mwai_mcp_callback</code> filters. See <code>dev-notes.md</code> for details.</p><p><b>Note:</b> This makes WordPress an MCP server. For connecting TO external MCP servers, use the Orchestration module.</p>', 'ai-engine' ),
KNOWLEDGE_INFO: __( 'Embeddings are textual data converted into vectors for similarity search. You can manage embeddings in the Knowledge tab, where you can switch from EDIT to AI SEARCH mode to query your knowledge base.<br/><br/>Embeddings are synchronized with vector databases like <a target="_blank" href="https://www.pinecone.io/">Pinecone</a> or Qdrant. You can create, edit, and search embeddings, then use Sync to process your posts and create/update embeddings as needed.<br/><br/>Both chatbots and AI Forms can use embeddings to enrich their answers with relevant context from your knowledge base.<br/><br/><b>If you want to discuss embeddings with other users, visit the <a href="https://discord.gg/bHDGh38" target="_blank">Meow Apps Discord Server</a>.</b>', 'ai-engine' ),
ORCHESTRATION_INFO: __( 'MCP servers extend AI capabilities by providing tools and functions that AI models can call during conversations. Configure external MCP servers here to give your chatbots access to specialized tools like web browsing, file system access, database queries, or custom business logic.<br/><br/>Each server requires a secure HTTPS URL implementing the MCP protocol and may require authentication via bearer token. Once configured, the tools from these servers become available to AI models through function calling.<br/><br/><b>Note:</b> This is for connecting TO external MCP servers. To make your WordPress accessible AS an MCP server for AI agents like Claude, use the MCP option under Remote Access.', 'ai-engine' ),
};
i18n.CHATBOT = {
CHATBOT_BUILDER: __( 'Chatbot Builder', 'ai-engine' ),
RESET_PARAMS: __( 'Reset Parameters', 'ai-engine' ),
};
i18n.STATISTICS = {
ABSOLUTE_HELP: __( 'Using Absolute, Day represents <i>today</i>. Otherwise, the <i>past 24 hours</i>. Same logic applies to the other timeframes.', 'ai-engine' ),
NO_CREDITS_MESSAGE: __( 'Message for No Credits', 'ai-engine' ),
FULL_ACCESS_USERS: __( 'Full-Access Users', 'ai-engine' ),
ENABLE_LIMITS: __( 'Enable Limits', 'ai-engine' ),
};
i18n.CONTENT_GENERATOR = {
INTRO: __( 'Generate high-quality articles with AI assistance. Create comprehensive content with customizable templates, writing styles, and automatic SEO optimization. Perfect for blogs, documentation, and marketing materials.', 'ai-engine' ),
TITLE_MISSING: __( 'Title is missing!', 'ai-engine' ),
SECTIONS_MISSING: __( 'Sections are missing!', 'ai-engine' ),
SINGLE_GENERATE: __( 'Single Generate', 'ai-engine' ),
BULK_GENERATE: __( 'Bulk Generate', 'ai-engine' ),
CONTENT_PARAMS: __( 'Content Params', 'ai-engine' ),
POST_PARAMS: __( 'Post Params', 'ai-engine' ),
CONTENT_PARAMS_INTRO: __( 'Input fields are displayed for certain placeholders used in prompts, such as {LANGUAGE} or {WRITING_TONE}', 'ai-engine' ),
CUSTOM_LANGUAGE: __( 'Custom Language', 'ai-engine' ),
WRITING_STYLE: __( 'Writing Style', 'ai-engine' ),
WRITING_TONE: __( 'Writing Tone', 'ai-engine' ),
CUSTOM_LANGUAGE_HELP: __( 'AI supports all languages with varying quality. <a href="https://meowapps.com/ai-engine/faq/#languages" target="_blank">Learn more</a>.', 'ai-engine' ),
MODEL_HELP: __( 'It is recommended to use Turbo or GPT-4 to write texts.', 'ai-engine' ),
PROMPTS_INTRO: __( 'Prompts represent the exact request sent to the AI. The variables between curly braces will be replaced by the content of the corresponding field. Prompts are saved in your templates.', 'ai-engine' ),
PROMPT_TITLE: __( 'Prompt for <b>Title</b>', 'ai-engine' ),
PROMPT_SECTIONS: __( 'Prompt for <b>Sections</b>', 'ai-engine' ),
PROMPT_CONTENT: __( 'Prompt for <b>Content</b>', 'ai-engine' ),
PROMPT_EXCERPT: __( 'Prompt for <b>Excerpt</b>', 'ai-engine' ),
POST_CREATED: __( 'Post Created', 'ai-engine' ),
POST_CREATED_AS_DRAFT: __( 'The post was created as a draft.', 'ai-engine' ),
CONTENT_HELP: __( 'You can modify the content before using "Create Post". Markdown is supported, and will be converted to HTML when the post is created.', 'ai-engine' ),
SECTIONS_HELP: __( 'Add, rewrite, remove, or reorganize those sections as you wish before (re)clicking on "Generate Content". Markdown format is recommended.', 'ai-engine' ),
GENERATE_EXCERPT: __( 'Generate Excerpt', 'ai-engine' ),
GENERATE_CONTENT: __( 'Generate Content', 'ai-engine' ),
GENERATE_SECTIONS: __( 'Generate Sections', 'ai-engine' ),
PARAGRAPHS_PER_SECTION: __( '# of Paragraphs per Section', 'ai-engine' ),
NUMBER_OF_SECTIONS: __( '# of Sections', 'ai-engine' ),
ADVICE: __( 'Advice', 'ai-engine' ),
SECTIONS: __( 'Sections', 'ai-engine' ),
USE_MAX_TOKENS: __( 'Use Max Tokens', 'ai-engine' ),
TOPICS_HELP: __( 'Write or paste your topics below. Each line will be used as a topic. The <b>Context</b> on the left will be applied to all topics. The same <b>Params</b> and <b>Prompts</b> will be used as with the <b>Single Generate</b>, so make sure you get satisfying results with it first. This <b>takes time</b>, so relax and enjoy some coffee ☕️ and tea 🍵 :)', 'ai-engine' ),
GENERATED_POSTS: __( 'Generated Posts', 'ai-engine' ),
USE_TOPICS_AS_TITLES: __( 'Use Topics as Titles', 'ai-engine' ),
NOTHING_YET: __( 'Nothing yet.', 'ai-engine' ),
BULK_ERROR_CONFIRM: __( 'An error was caught ({MESSAGE}). Should we continue?', 'ai-engine' ),
GENERATE_ALL: __( 'Generate All', 'ai-engine' ),
EDIT_POST: __( 'Edit Post', 'ai-engine' ),
CREATE_POST: __( 'Create Post', 'ai-engine' ),
TITLE_TOO_SHORT: __( 'The title is too short. It should be at least 3 words.', 'ai-engine' ),
TITLE_TOO_SHORT_2: __( 'The title is too short. It should be at least 40 characters.', 'ai-engine' ),
TITLE_TOO_LONG: __( 'The title is too long. It should be less than 8 words.', 'ai-engine' ),
TITLE_TOO_LONG_2: __( 'The title is too long. It should be less than 70 characters.', 'ai-engine' ),
};
i18n.TEMPLATES = {
TEMPLATE: __( 'Template', 'ai-engine' ),
TEMPLATES: __( 'Templates', 'ai-engine' ),
DELETE_CONFIRM: __( 'Are you sure you want to delete this template?', 'ai-engine' ),
DELETE_ALL_CONFIRM: __( 'Are you sure you want to delete all the templates?', 'ai-engine' ),
NEW_TEMPLATE_NAME: __( 'New Template', 'ai-engine' ),
EDIT: __( 'EDIT', 'ai-engine' )
};
i18n.PLAYGROUND = {
INTRO: __( 'Welcome to the AI Playground! Here, you can play with different AI models and ask the UI to perform various tasks for you. You can ask it to write, rewrite, or translate an article, categorize words or elements into groups, write an email, etc. <b>Let me know if there are any new features you would like to see!</b> Have fun 🥳', 'ai-engine' ),
PROMPT: __( 'Query / Prompt', 'ai-engine' ),
REPLY: __( 'Reply', 'ai-engine' ),
};
i18n.ALERTS = {
FINETUNING_STARTED: __( 'Fine-tuning started! Check its progress in the Models section. Depending on your dataset size, it may take a while (from a few minutes to days).', 'ai-engine' ),
RESET_BUILDER: __( 'This will delete all the rows in the builder. Are you sure?', 'ai-engine' ),
DELETE_FINETUNE: __( 'You are going to delete this fine-tune. Are you sure?\n\nPlease note that it will take a while before it is actually deleted. This might be a temporary issue of OpenAI.', 'ai-engine' ),
FINETUNE_ALREADY_DELETED: __( 'This fine-tune was already deleted. It will be removed from the list.', 'ai-engine' ),
CHECK_CONSOLE: __( 'Error! Check your console for more details.', 'ai-engine' ),
DATASET_UPLOADED: __( 'Uploaded successfully! You can now train a model based on this dataset.', 'ai-engine' ),
ONLY_SUPPORTS_FILES: __( 'This only supports JSON, JSONL, and CSV files. Check the Instructions section below.', 'ai-engine' ),
EMPTY_LINES_DATASET: __( 'Some lines were empty. Make sure the CSV has a header row and that the columns are named \'prompt\' and \'completion\'. For debugging, an empty line was logged to the console.', 'ai-engine' ),
EMPTY_LINES_EMBEDDINGS: __( 'Some lines were empty. Make sure the CSV has a header row and that the columns are named \'title\' and \'content\'. For debugging, an empty line was logged to the console.', 'ai-engine' ),
ARE_YOU_SURE: __( 'Are you sure?', 'ai-engine' ),
};
i18n.FINETUNING = {
MODELS_INTRO: __( 'The AI models you have fine-tuned. To create more, visit <b>Files</b>.', 'ai-engine' ),
LEGACY_MODELS_INTRO: __( 'The AI models you have fine-tuned. <b>Do not use legacy fine-tuning anymore (based on models prior to GPT 3.5). Their deprecation has been <a href="https://platform.openai.com/docs/guides/legacy-fine-tuning" target="_blank">announced by OpenAI</a> for January 4th, 2024.</b><br />', 'ai-engine' ),
FILES_INTRO: __( 'The files you have uploaded to OpenAI. To create a new dataset file, switch from <b>Model & Files</b> to <b>Dataset Editor</b>. To train a new model, click on the <i>magic wand</i>.', 'ai-engine' ),
MODEL_FINETUNE: __( 'Model Finetune', 'ai-engine' ),
MODELS_FILES: __( 'Models & Files', 'ai-engine' ),
DATASET_EDITOR: __( 'Dataset Editor', 'ai-engine' ),
EDITOR: __( 'Editor', 'ai-engine' ),
GENERATOR: __( 'Generator', 'ai-engine' ),
HUGE_DATASET_WARNING: __( 'Caution: The data is too large to be saved in your browser\'s local storage.', 'ai-engine' ),
NO_FINETUNES_YET: __( 'No fine-tunes found. Refresh the list, or create a new one (via a dataset).', 'ai-engine' ),
CLEAN_MODELS_LIST: __( 'Clean Models List', 'ai-engine' ),
DELETED_FINETUNE_ISSUE: __( 'For some reason, OpenAI still return the models even after you deleted them. Don\'t worry, AI Engine will do the cleanup for you! You can force the cleanup by using this button. It takes a bit of time depending on the total of models you have.', 'ai-engine' ),
};
i18n.EMBEDDINGS = {
EDIT: __( 'EDIT', 'ai-engine' ),
AI_SEARCH: __( 'AI SEARCH', 'ai-engine' ),
SYNC_POSTS: __( 'Sync Posts', 'ai-engine' ),
AUTO_SYNC_POSTS: __( 'Auto-Sync Posts', 'ai-engine' ),
AUTO_SYNC_POSTS_DESCRIPTION: __( 'Embeddings will be created, updated or removed based on the activity related to your posts.', 'ai-engine' ),
REWRITE_CONTENT: __( 'Rewrite Content', 'ai-engine' ),
REWRITE_CONTENT_DESCRIPTION: __( 'Shorten and improve the content for your embedding using the default model.', 'ai-engine' ),
FORCE_RECREATE: __( 'Force Recreate', 'ai-engine' ),
FORCE_RECREATE_DESCRIPTION: __( 'Force recreation of existing embeddings even when content, model, and dimensions haven\'t changed. Note: New posts without embeddings will always be synced regardless of this setting.', 'ai-engine' ),
DELETE_ALL_EMBEDDINGS: __( 'Delete All Embeddings', 'ai-engine' ),
DELETE_ALL_EMBEDDINGS_CONFIRM: __( 'Are you sure you want to delete all the embeddings in this environment?', 'ai-engine' ),
REWRITE_PROMPT_DESCRIPTION: __( 'Prompt for the rewrite. Supports {CONTENT}, {TITLE}, {URL}, {EXCERPT}, {LANGUAGE}, {ID}.', 'ai-engine' ),
SYNC_ALL: __( 'Sync All', 'ai-engine' ),
SYNC_ONE: __( 'Sync One', 'ai-engine' ),
ADD_INDEX: __( 'Add Index', 'ai-engine' ),
ADD_INDEX_DESCRIPTION: __( 'An index is like a database, and contains embeddings. You can have many indexes and switch between them. The indexes are hosted on Pinecone.', 'ai-engine' ),
NO_NAMESPACE_SUPPORT: __( 'Note: This server does not support namespaces.', 'ai-engine' ),
};
i18n.ERROR = {
UPDATING_OPTIONS: __( 'An error occurred while updating the options.' ),
GETTING_OPTIONS: __( 'An error occurred while getting the options.' ),
CHECK_YOUR_CONSOLE: __( 'For more information, check <a target="_blank" href="https://meowapps.com/tutorial-network-activity-dev-tools/">your console</a>. You might also want to check your <a target="_blank" href="https://meowapps.com/tutorial-php-error-logs/">PHP Error Logs</a>.', 'ai-engine' ),
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (i18n);
/***/ }),
/***/ "./app/js/blocks/ChatbotBlock.js":
/*!***************************************!*\
!*** ./app/js/blocks/ChatbotBlock.js ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_screens_chatbots_Params__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/screens/chatbots/Params */ "./app/js/screens/chatbots/Params.js");
const defaultShortcodeParams = (_app_settings__WEBPACK_IMPORTED_MODULE_0__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_0__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_0__.options.chatbot_defaults) || {};
const {
registerBlockType
} = wp.blocks;
const {
useMemo,
useState,
useEffect
} = wp.element;
const {
PanelBody,
SelectControl,
ToggleControl
} = wp.components;
const {
InspectorControls,
useBlockProps
} = wp.blockEditor;
const transformKey = key => {
return key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
};
const saveChatbot = props => {
const {
attributes: {
chatbotId,
isCustomChatbot,
shortcodeParams
}
} = props;
if (isCustomChatbot) {
// Create the shortcode from shortcodeParams
const shortcode = Object.entries(shortcodeParams).filter(([, value]) => value !== null && value !== undefined && value !== '').reduce((acc, [key, value]) => {
const transformedKey = transformKey(key);
const encodedValue = encodeURIComponent(value); // Encode the value
// With custom chatbots, we need to use 'customId' instead of 'botId'
if (transformedKey === 'bot_id') {
return `${acc} custom_id="${encodedValue}"`;
}
return `${acc} ${transformedKey}="${encodedValue}"`;
}, "[mwai_chatbot");
return `${shortcode}]`;
} else {
// Use the existing logic for non-custom chatbots
const shortcodeAttributes = {
id: {
value: chatbotId,
insertIfNull: true
}
};
const shortcode = Object.entries(shortcodeAttributes).filter(([, {
value,
insertIfNull
}]) => !!value || insertIfNull).reduce((acc, [key, {
value
}]) => {
const transformedKey = transformKey(key);
const encodedValue = encodeURIComponent(value); // Encode the value
return `${acc} ${transformedKey}="${encodedValue}"`;
}, "[mwai_chatbot");
return `${shortcode}]`;
}
};
const ChatbotBlock = props => {
const {
attributes: {
chatbotId,
isCustomChatbot,
shortcodeParams
},
setAttributes,
isSelected
} = props;
const [localShortcodeParams, setLocalShortcodeParams] = useState(() => {
return Object.keys(shortcodeParams || {}).length ? shortcodeParams : defaultShortcodeParams;
});
useEffect(() => {
if (isCustomChatbot && (!shortcodeParams || !Object.keys(shortcodeParams).length)) {
setLocalShortcodeParams(defaultShortcodeParams);
setAttributes({
shortcodeParams: defaultShortcodeParams
});
}
}, [isCustomChatbot]);
const blockProps = useBlockProps();
const chatbotsOptions = useMemo(() => {
const freshChatbots = _app_settings__WEBPACK_IMPORTED_MODULE_0__.chatbots.map(chatbot => ({
label: chatbot.name,
value: chatbot.botId
}));
freshChatbots.unshift({
label: 'None',
value: null
});
return freshChatbots;
}, [_app_settings__WEBPACK_IMPORTED_MODULE_0__.chatbots]);
const currentChatbot = useMemo(() => {
return _app_settings__WEBPACK_IMPORTED_MODULE_0__.chatbots.find(chatbot => chatbot.botId === chatbotId);
}, [chatbotId]);
const title = useMemo(() => {
if (isCustomChatbot) return 'Custom Chatbot';
return currentChatbot ? `Chatbot (${currentChatbot.name})` : 'Chatbot';
}, [isCustomChatbot, chatbotId, currentChatbot]);
const updateShortcodeParams = (value, name) => {
// Old Code which was using a newParams directly with everything
// setLocalShortcodeParams(newParams);
// setAttributes({ shortcodeParams: newParams });
// New code
const newParams = {
...localShortcodeParams
};
newParams[name] = value;
setLocalShortcodeParams(newParams);
setAttributes({
shortcodeParams: newParams
});
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_1__.AiBlockContainer, {
title: title,
type: "chatbot",
isSelected: isSelected
}, isCustomChatbot && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_screens_chatbots_Params__WEBPACK_IMPORTED_MODULE_2__["default"], {
shortcodeParams: localShortcodeParams,
updateShortcodeParams: updateShortcodeParams,
options: _app_settings__WEBPACK_IMPORTED_MODULE_0__.options,
blockMode: true
})), !isCustomChatbot && /*#__PURE__*/React.createElement("p", null, "Selected chatbot: ", currentChatbot ? currentChatbot.name : 'None'))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT
}, /*#__PURE__*/React.createElement(ToggleControl, {
label: "Custom Chatbot",
checked: isCustomChatbot,
onChange: value => setAttributes({
isCustomChatbot: value
})
}), !isCustomChatbot && chatbotsOptions && chatbotsOptions.length > 0 && /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT,
value: chatbotId,
options: chatbotsOptions,
onChange: value => setAttributes({
chatbotId: value
})
})), !isCustomChatbot && /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SETTINGS
})));
};
const createChatbotBlock = () => {
registerBlockType('ai-engine/chatbot', {
title: 'AI Chatbot',
description: "Embed an AI Engine Chatbot in your content.",
icon: _common__WEBPACK_IMPORTED_MODULE_1__.meowIcon,
category: 'layout',
keywords: ['ai', 'openai', 'chatbot'],
attributes: {
id: {
type: 'string',
default: ''
},
chatbotId: {
type: 'string',
default: 'default'
},
isCustomChatbot: {
type: 'boolean',
default: false
},
shortcodeParams: {
type: 'object',
default: defaultShortcodeParams
}
},
edit: ChatbotBlock,
save: saveChatbot
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createChatbotBlock);
/***/ }),
/***/ "./app/js/blocks/DiscussionsBlock.js":
/*!*******************************************!*\
!*** ./app/js/blocks/DiscussionsBlock.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
const {
registerBlockType
} = wp.blocks;
const {
useMemo
} = wp.element;
const {
PanelBody,
SelectControl,
ToggleControl,
TextControl
} = wp.components;
const {
InspectorControls,
useBlockProps
} = wp.blockEditor;
const transformKey = key => {
return key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
};
const saveDiscussions = props => {
const {
attributes: {
isCustomChatbot,
chatbotId,
customId,
textNewChat
}
} = props;
const shortcodeAttributes = {};
if (isCustomChatbot) {
if (customId) {
shortcodeAttributes.customId = customId;
}
} else {
if (chatbotId) {
shortcodeAttributes.id = chatbotId;
}
}
if (textNewChat) {
shortcodeAttributes.textNewChat = textNewChat;
}
const shortcode = Object.entries(shortcodeAttributes).filter(([, value]) => value !== null && value !== undefined && value !== '').reduce((acc, [key, value]) => {
const transformedKey = transformKey(key);
return `${acc} ${transformedKey}="${value}"`;
}, "[mwai_discussions");
return `${shortcode}]`;
};
const DiscussionsBlock = props => {
const {
attributes: {
isCustomChatbot,
chatbotId,
customId,
textNewChat
},
setAttributes,
isSelected
} = props;
const blockProps = useBlockProps();
const chatbotsOptions = useMemo(() => {
const freshChatbots = _app_settings__WEBPACK_IMPORTED_MODULE_0__.chatbots.map(chatbot => ({
label: chatbot.name,
value: chatbot.botId
}));
freshChatbots.unshift({
label: 'None',
value: ''
});
return freshChatbots;
}, [_app_settings__WEBPACK_IMPORTED_MODULE_0__.chatbots]);
const currentChatbot = useMemo(() => {
return _app_settings__WEBPACK_IMPORTED_MODULE_0__.chatbots.find(chatbot => chatbot.botId === chatbotId);
}, [chatbotId]);
const title = useMemo(() => {
if (isCustomChatbot) return 'Discussions (Custom Chatbot)';
return currentChatbot ? `Discussions (${currentChatbot.name})` : 'Discussions';
}, [isCustomChatbot, currentChatbot]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_1__.AiBlockContainer, {
title: title,
type: "discussions",
isSelected: isSelected
}, /*#__PURE__*/React.createElement("span", null, isCustomChatbot ? `Custom ID: ${customId || 'None'}` : `Selected chatbot: ${currentChatbot ? currentChatbot.name : 'None'}`), /*#__PURE__*/React.createElement("span", null, "New Chat: ", textNewChat || 'Default'))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: "Discussions Settings"
}, /*#__PURE__*/React.createElement(ToggleControl, {
label: "Custom Chatbot",
checked: isCustomChatbot,
onChange: value => setAttributes({
isCustomChatbot: value
})
}), isCustomChatbot ? /*#__PURE__*/React.createElement(TextControl, {
label: "Custom Chatbot ID",
value: customId,
onChange: value => setAttributes({
customId: value
})
}) : /*#__PURE__*/React.createElement(SelectControl, {
label: "Select Chatbot",
value: chatbotId,
options: chatbotsOptions,
onChange: value => setAttributes({
chatbotId: value
})
}), /*#__PURE__*/React.createElement(TextControl, {
label: "Text for New Chat Button",
value: textNewChat,
onChange: value => setAttributes({
textNewChat: value
})
}))));
};
const createDiscussionsBlock = () => {
registerBlockType('ai-engine/discussions', {
title: 'AI Discussions',
description: "Embed AI Engine Discussions in your content.",
icon: _common__WEBPACK_IMPORTED_MODULE_1__.meowIcon,
category: 'layout',
keywords: ['ai', 'openai', 'discussions'],
attributes: {
isCustomChatbot: {
type: 'boolean',
default: false
},
chatbotId: {
type: 'string',
default: ''
},
customId: {
type: 'string',
default: ''
},
textNewChat: {
type: 'string',
default: ''
}
},
edit: DiscussionsBlock,
save: saveDiscussions
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createDiscussionsBlock);
/***/ }),
/***/ "./app/js/blocks/FormConditionalBlock.js":
/*!***********************************************!*\
!*** ./app/js/blocks/FormConditionalBlock.js ***!
\***********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useEffect,
useMemo
} = wp.element;
const {
PanelBody,
TextControl,
SelectControl,
Button
} = wp.components;
const {
InspectorControls,
InnerBlocks,
useBlockProps
} = wp.blockEditor;
const {
useSelect
} = wp.data;
const saveConditionalBlock = props => {
const {
attributes: {
id,
conditions = [],
logic = 'AND',
conditionField,
conditionValue
}
} = props;
const blockProps = useBlockProps.save();
let shortcode = `[mwai-form-conditional id="${id}"`;
const conds = conditions.length ? conditions : conditionField ? [{
field: conditionField,
operator: 'eq',
value: conditionValue
}] : [];
if (conds.length) {
shortcode += ` conditions="${encodeURIComponent(JSON.stringify(conds))}" logic="${logic}"`;
}
shortcode += ']';
return /*#__PURE__*/React.createElement("div", _extends({}, blockProps, {
id: `mwai-form-conditional-${id}`,
className: "mwai-form-conditional",
style: {
display: 'none'
}
}), shortcode, /*#__PURE__*/React.createElement(InnerBlocks.Content, null));
};
const operatorOptions = [{
label: 'Equals',
value: 'eq'
}, {
label: 'Not Equals',
value: 'neq'
}, {
label: 'Contains',
value: 'contains'
}, {
label: 'Does Not Contain',
value: 'not_contains'
}, {
label: 'Is Empty',
value: 'empty'
}, {
label: 'Is Not Empty',
value: 'not_empty'
}];
const logicOptions = [{
label: 'AND',
value: 'AND'
}, {
label: 'OR',
value: 'OR'
}];
const FormConditionalBlock = props => {
const {
attributes: {
id,
conditions = [],
logic = 'AND',
conditionField,
conditionValue
},
setAttributes,
clientId
} = props;
const blockProps = useBlockProps();
useEffect(() => {
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: newId
});
}
if (!conditions.length && (conditionField || conditionValue)) {
setAttributes({
conditions: [{
field: conditionField,
operator: 'eq',
value: conditionValue
}]
});
}
}, [id]);
const fields = useSelect(select => {
const {
getBlock,
getBlockRootClientId
} = select('core/block-editor');
let parentId = getBlockRootClientId(clientId);
while (parentId) {
const parentBlock = getBlock(parentId);
if ((parentBlock === null || parentBlock === void 0 ? void 0 : parentBlock.name) === 'ai-engine/form-container') {
break;
}
parentId = getBlockRootClientId(parentId);
}
const names = [];
if (parentId) {
const containerBlock = getBlock(parentId);
const gatherNames = block => {
var _block$attributes;
if (block.name === 'ai-engine/form-field' && (_block$attributes = block.attributes) !== null && _block$attributes !== void 0 && _block$attributes.name) {
names.push(block.attributes.name);
}
if (block.innerBlocks) {
block.innerBlocks.forEach(gatherNames);
}
};
containerBlock.innerBlocks.forEach(gatherNames);
}
return names;
}, [clientId]);
const fieldOptions = useMemo(() => {
const opts = fields.map(n => ({
label: n,
value: n
}));
opts.unshift({
label: '[N/A]',
value: ''
});
return opts;
}, [fields]);
useEffect(() => {
if (fields.length === 1 && conditions.some(c => !c.field)) {
const defField = fields[0];
const updated = conditions.map(c => c.field ? c : {
...c,
field: defField
});
setAttributes({
conditions: updated
});
}
}, [fields, conditions]);
const hint = useMemo(() => {
const hasProblem = conditions.length === 0 || conditions.some(c => !c.field);
if (hasProblem) {
return /*#__PURE__*/React.createElement("span", {
className: "mwai-pill mwai-pill-red"
}, "[N/A]");
}
return /*#__PURE__*/React.createElement("span", {
className: "mwai-pill"
}, conditions.length, " condition", conditions.length > 1 ? 's' : '');
}, [conditions]);
const conditionsSummary = useMemo(() => {
if (!conditions.length) return null;
const operatorLabels = {
'eq': '=',
'neq': '≠',
'contains': 'contains',
'not_contains': 'does not contain',
'empty': 'is empty',
'not_empty': 'is not empty'
};
return conditions.map((cond, index) => {
if (!cond.field) return null;
const operator = operatorLabels[cond.operator] || cond.operator;
let conditionText = `${cond.field} ${operator}`;
if (cond.operator !== 'empty' && cond.operator !== 'not_empty' && cond.value) {
conditionText += ` "${cond.value}"`;
}
return /*#__PURE__*/React.createElement("div", {
key: index,
style: {
fontSize: '12px',
color: '#666',
marginBottom: '4px',
fontFamily: 'monospace',
padding: '4px 8px',
background: '#f5f5f5',
borderRadius: '3px'
}
}, conditionText, index < conditions.length - 1 && /*#__PURE__*/React.createElement("span", {
style: {
color: '#0073aa',
fontWeight: 'bold',
marginLeft: '8px'
}
}, logic));
}).filter(Boolean);
}, [conditions, logic]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_0__.AiBlockContainer, {
title: "Conditional",
type: "conditional",
isDisplayed: true,
hint: hint
}, conditionsSummary && conditionsSummary.length > 0 && /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: '12px',
padding: '8px',
background: '#fafafa',
border: '1px solid #e0e0e0',
borderRadius: '4px'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '11px',
textTransform: 'uppercase',
color: '#999',
marginBottom: '6px',
fontWeight: '600'
}
}, "Conditions:"), conditionsSummary), /*#__PURE__*/React.createElement(InnerBlocks, null))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.CONDITIONS
}, conditions.map((cond, index) => /*#__PURE__*/React.createElement("div", {
key: index,
style: {
marginBottom: '8px'
},
className: "mwai-condition-panel"
}, /*#__PURE__*/React.createElement(PanelBody, {
title: `${_root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.CONDITION} ${index + 1}`,
initialOpen: true
}, /*#__PURE__*/React.createElement(SelectControl, {
label: "Field",
value: cond.field,
options: fieldOptions,
onChange: value => {
const newConds = [...conditions];
newConds[index].field = value;
setAttributes({
conditions: newConds
});
}
}), /*#__PURE__*/React.createElement(SelectControl, {
label: "Operator",
value: cond.operator,
options: operatorOptions,
onChange: value => {
const newConds = [...conditions];
newConds[index].operator = value;
setAttributes({
conditions: newConds
});
}
}), cond.operator !== 'empty' && cond.operator !== 'not_empty' && /*#__PURE__*/React.createElement(TextControl, {
label: "Value",
value: cond.value,
onChange: value => {
const newConds = [...conditions];
newConds[index].value = value;
setAttributes({
conditions: newConds
});
}
}), /*#__PURE__*/React.createElement(Button, {
isSecondary: true,
isDestructive: true,
icon: "trash",
style: {
width: '100%'
},
onClick: () => {
const newConds = conditions.filter((_, i) => i !== index);
setAttributes({
conditions: newConds
});
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.REMOVE)), index < conditions.length - 1 && /*#__PURE__*/React.createElement(SelectControl, {
label: "",
value: logic,
options: logicOptions,
onChange: value => setAttributes({
logic: value
})
}))), /*#__PURE__*/React.createElement(Button, {
isPrimary: true,
style: {
width: '100%',
marginBottom: '8px'
},
icon: "plus",
onClick: () => {
const defaultField = fields.length === 1 ? fields[0] : '';
setAttributes({
conditions: [...conditions, {
field: defaultField,
operator: 'eq',
value: ''
}]
});
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.ADD_CONDITION), /*#__PURE__*/React.createElement(TextControl, {
label: "ID",
value: id,
onChange: value => setAttributes({
id: value
})
}))));
};
const createConditionalBlock = () => {
registerBlockType('ai-engine/form-conditional', {
title: 'AI Form Conditional',
description: 'Display inner blocks only when a condition is met.',
icon: _common__WEBPACK_IMPORTED_MODULE_0__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form')],
attributes: {
id: {
type: 'string',
default: ''
},
conditions: {
type: 'array',
default: []
},
logic: {
type: 'string',
default: 'AND'
},
// Legacy attributes
conditionField: {
type: 'string',
default: ''
},
conditionValue: {
type: 'string',
default: ''
}
},
edit: FormConditionalBlock,
save: saveConditionalBlock
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createConditionalBlock);
/***/ }),
/***/ "./app/js/blocks/FormContainerBlock.js":
/*!*********************************************!*\
!*** ./app/js/blocks/FormContainerBlock.js ***!
\*********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useEffect
} = wp.element;
const {
PanelBody,
SelectControl,
TextControl
} = wp.components;
const {
InspectorControls,
InnerBlocks,
useBlockProps
} = wp.blockEditor;
const saveFormField = props => {
const blockProps = useBlockProps.save();
const {
attributes: {
id,
theme
}
} = props;
const shortcode = `[mwai-form-container id="${id}" theme="${theme}"]`;
return /*#__PURE__*/React.createElement("div", _extends({}, blockProps, {
id: `mwai-form-container-${id}`,
className: "mwai-form-container"
}), shortcode, /*#__PURE__*/React.createElement(InnerBlocks.Content, null));
};
const FormContainerBlock = props => {
const {
attributes: {
id,
theme
},
setAttributes
} = props;
const blockProps = useBlockProps();
useEffect(() => {
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: newId
});
}
}, [id]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_0__.AiBlockContainer, {
title: "Container",
type: "container",
isDisplayed: true
}, /*#__PURE__*/React.createElement(InnerBlocks, null))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.STYLE
}, /*#__PURE__*/React.createElement("p", null, "The theme will be applied to all the AI elements in this container."), /*#__PURE__*/React.createElement(SelectControl, {
label: "Theme",
value: theme,
onChange: value => setAttributes({
theme: value
}),
options: [{
label: 'None',
value: 'none'
}, {
label: 'ChatGPT',
value: 'ChatGPT'
}, {
label: 'Timeless',
value: 'Timeless'
}]
}), /*#__PURE__*/React.createElement(TextControl, {
label: "ID",
value: id,
onChange: value => setAttributes({
id: value
})
}))));
};
const createContainerBlock = () => {
registerBlockType('ai-engine/form-container', {
title: 'AI Form Container',
description: 'Container to embed the blocks relative to a specific AI Form.',
icon: _common__WEBPACK_IMPORTED_MODULE_0__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form')],
attributes: {
id: {
type: 'string',
default: ''
},
theme: {
type: 'string',
default: 'ChatGPT'
}
},
edit: FormContainerBlock,
save: saveFormField
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createContainerBlock);
/***/ }),
/***/ "./app/js/blocks/FormFieldBlock.js":
/*!*****************************************!*\
!*** ./app/js/blocks/FormFieldBlock.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useEffect
} = wp.element;
const {
Button,
PanelBody,
TextControl,
SelectControl,
CheckboxControl
} = wp.components;
const {
useBlockProps,
InspectorControls
} = wp.blockEditor;
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const saveFormField = props => {
const {
attributes: {
id,
label,
type,
name,
options = [],
placeholder,
rows,
defaultValue,
maxlength,
required
}
} = props;
const encodedOptions = encodeURIComponent((0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(options));
const blockProps = useBlockProps.save();
// Build shortcode
let shortcode = '[mwai-form-field';
if (id) {
shortcode += ` id="${id}"`;
}
if (label) {
shortcode += ` label="${label}"`;
}
if (type) {
shortcode += ` type="${type}"`;
}
if (name) {
shortcode += ` name="${name}"`;
}
if (encodedOptions) {
shortcode += ` options="${encodedOptions}"`;
}
if (placeholder) {
shortcode += ` placeholder="${placeholder}"`;
}
if (type === 'textarea' && rows) {
shortcode += ` rows="${rows}"`;
}
if (defaultValue) {
shortcode += ` default="${defaultValue}"`;
}
if (maxlength) {
shortcode += ` maxlength="${maxlength}"`;
}
if (required) {
shortcode += ` required="${required}"`;
}
shortcode += ']';
return /*#__PURE__*/React.createElement("div", blockProps, shortcode);
};
const FormFieldBlock = props => {
const {
attributes: {
id,
type,
name,
options = [],
label,
placeholder,
rows,
defaultValue,
maxlength,
required
},
setAttributes,
isSelected
} = props;
const blockProps = useBlockProps();
useEffect(() => {
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: 'mwai-' + newId
});
}
}, [id]);
const onUpdateLabel = value => {
setAttributes({
label: value
});
const newName = value.trim().replace(/ /g, '_').replace(/[^\w-]+/g, '').toUpperCase();
if (newName) {
setAttributes({
name: newName
});
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_1__.AiBlockContainer, {
title: `${capitalizeFirstLetter(type)}`,
type: "field",
isSelected: isSelected,
hint: /*#__PURE__*/React.createElement("span", {
className: "mwai-pill"
}, '{', name, '}')
}, /*#__PURE__*/React.createElement("div", null, label), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement("div", null, name))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: __('Field')
}, /*#__PURE__*/React.createElement(TextControl, {
label: "Label Text",
value: label,
onChange: onUpdateLabel
}), /*#__PURE__*/React.createElement(TextControl, {
label: "Field Name",
value: name,
onChange: value => setAttributes({
name: value
})
}), /*#__PURE__*/React.createElement(SelectControl, {
label: "Field Type",
value: type,
onChange: value => setAttributes({
type: value
}),
options: [{
label: 'Input',
value: 'input'
}, {
label: 'Select',
value: 'select'
}, {
label: 'Checkbox',
value: 'checkbox'
}, {
label: 'Radio',
value: 'radio'
}, {
label: 'Text Area',
value: 'textarea'
}]
}), (type === 'input' || type === 'textarea') && /*#__PURE__*/React.createElement(TextControl, {
label: "Placeholder",
value: placeholder,
onChange: value => setAttributes({
placeholder: value
})
}), (type === 'input' || type === 'textarea') && /*#__PURE__*/React.createElement(TextControl, {
label: "Default Value",
value: defaultValue,
onChange: value => setAttributes({
defaultValue: value
})
}), (type === 'input' || type === 'textarea') && /*#__PURE__*/React.createElement(TextControl, {
label: "Max Length",
value: maxlength,
onChange: value => setAttributes({
maxlength: value
})
}), type === 'textarea' && /*#__PURE__*/React.createElement(TextControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ROWS,
value: rows,
onChange: value => setAttributes({
rows: value
}),
type: "number",
step: "1",
min: "1",
max: "100"
}), /*#__PURE__*/React.createElement(CheckboxControl, {
label: "Required",
checked: required,
onChange: value => setAttributes({
required: value
})
})), (type === 'select' || type === 'radio' || type === 'checkbox') && /*#__PURE__*/React.createElement(PanelBody, {
title: /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%'
}
}, /*#__PURE__*/React.createElement("div", null, __('Options')))
}, options.map((option, index) => {
return /*#__PURE__*/React.createElement("div", {
key: index,
style: {
display: 'flex',
marginBottom: -25
}
}, /*#__PURE__*/React.createElement("div", {
style: {
marginRight: 5
}
}, /*#__PURE__*/React.createElement(TextControl, {
style: {
marginRight: 10
},
label: "Label",
isInline: true,
value: option.label,
onChange: value => {
const newOptions = [...options];
newOptions[index].label = value;
setAttributes({
options: newOptions
});
}
})), /*#__PURE__*/React.createElement(TextControl, {
style: {},
label: "Value",
isSubtle: true,
value: option.value,
onChange: value => {
const newOptions = [...options];
newOptions[index].value = value;
setAttributes({
options: newOptions
});
}
}), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 5,
position: 'relative',
top: 23
}
}, /*#__PURE__*/React.createElement(Button, {
style: {
height: 30
},
isDestructive: true,
icon: "trash",
isSmall: true,
onClick: () => {
const newOptions = [...options];
newOptions.splice(index, 1);
setAttributes({
options: newOptions
});
}
})));
}), /*#__PURE__*/React.createElement(Button, {
isPrimary: true,
style: {
width: '100%',
marginTop: 10
},
onClick: () => {
//ev.preventDefault();
//ev.stopPropagation();
const newOptions = [...options];
newOptions.push({
label: '',
value: ''
});
setAttributes({
options: newOptions
});
}
}, "Add Option")), /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SYSTEM
}, /*#__PURE__*/React.createElement(TextControl, {
label: "ID",
value: id,
onChange: value => setAttributes({
id: value
})
}))));
};
const createFormFieldBlock = () => {
registerBlockType('ai-engine/form-field', {
apiVersion: 3,
title: 'AI Form Field',
description: 'An AI Field for your AI Form.',
icon: _common__WEBPACK_IMPORTED_MODULE_1__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form')],
supports: {
dimensions: {
width: true
}
},
attributes: {
id: {
type: 'string',
default: ''
},
name: {
type: 'string',
default: 'LABEL'
},
type: {
type: 'string',
default: 'input'
},
options: {
type: 'array',
default: []
},
label: {
type: 'string',
default: 'Label: '
},
placeholder: {
type: 'string',
default: ''
},
defaultValue: {
type: 'string',
default: ''
},
maxlength: {
type: 'string',
default: ''
},
rows: {
type: 'rows',
default: 4
},
required: {
type: 'boolean',
default: true
}
},
edit: FormFieldBlock,
save: saveFormField
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createFormFieldBlock);
/***/ }),
/***/ "./app/js/blocks/FormOutputBlock.js":
/*!******************************************!*\
!*** ./app/js/blocks/FormOutputBlock.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useEffect
} = wp.element;
const {
PanelBody,
TextControl,
CheckboxControl
} = wp.components;
const {
InspectorControls,
useBlockProps
} = wp.blockEditor;
const saveFormField = props => {
const {
attributes: {
id,
copyButton
}
} = props;
const blockProps = useBlockProps.save();
// Shortcode attributes
const shortcodeAttributes = {
id: {
value: id,
insertIfNull: true
},
copy_button: {
value: copyButton,
insertIfNull: false
}
};
// Create the shortcode
let shortcode = Object.entries(shortcodeAttributes).filter(([, {
value,
insertIfNull
}]) => value !== false && value !== '' || insertIfNull).reduce((acc, [key, {
value
}]) => `${acc} ${key}="${value}"`, "[mwai-form-output");
shortcode = `${shortcode}]`;
// Return the shortcode
return /*#__PURE__*/React.createElement("div", blockProps, shortcode);
};
const FormOutputBlock = props => {
const {
attributes: {
id,
copyButton
},
setAttributes,
isSelected
} = props;
const blockProps = useBlockProps();
useEffect(() => {
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: 'mwai-' + newId
});
}
}, [id]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_0__.AiBlockContainer, {
title: "Output",
type: "output",
isSelected: isSelected,
hint: /*#__PURE__*/React.createElement("span", {
className: "mwai-pill mwai-pill-purple"
}, "#", id)
}, /*#__PURE__*/React.createElement("div", null), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement("div", null, "#", id))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].FORMS.OUTPUT
}, /*#__PURE__*/React.createElement(CheckboxControl, {
label: "Copy Button",
checked: copyButton,
onChange: value => setAttributes({
copyButton: value
})
}), /*#__PURE__*/React.createElement(TextControl, {
label: "ID",
value: id,
onChange: value => setAttributes({
id: value
})
}))));
};
const createOutputBlock = () => {
registerBlockType('ai-engine/form-output', {
title: 'AI Form Output',
description: 'An Output Field for your AI Form.',
icon: _common__WEBPACK_IMPORTED_MODULE_0__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form')],
supports: {
dimensions: {
minHeight: true
}
},
attributes: {
id: {
type: 'string',
default: ''
},
copyButton: {
type: 'boolean',
default: true
}
},
edit: FormOutputBlock,
save: saveFormField
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createOutputBlock);
/***/ }),
/***/ "./app/js/blocks/FormResetBlock.js":
/*!*****************************************!*\
!*** ./app/js/blocks/FormResetBlock.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
// FormResetBlock.js
// AI Engine
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useMemo,
useEffect
} = wp.element;
const {
PanelBody,
TextControl,
CheckboxControl
} = wp.components;
const {
InspectorControls,
useBlockProps
} = wp.blockEditor;
/**
* This function generates the *frontend* output of the block:
* A shortcode like: [mwai-form-reset id="..." label="..."]
*/
const saveResetBlock = props => {
const {
attributes: {
id,
label,
localMemory
}
} = props;
const blockProps = useBlockProps.save();
// Build shortcode from attributes
let shortcode = `[mwai-form-reset id="${id}" label="${label}"`;
if (localMemory) {
shortcode += ` local_memory="true"`;
}
shortcode += `]`;
return /*#__PURE__*/React.createElement("div", blockProps, shortcode);
};
/**
* The "edit" component defines the block’s UI in the editor.
*/
const FormResetBlock = props => {
const blockProps = useBlockProps();
const {
attributes: {
id,
label,
localMemory
},
setAttributes,
isSelected
} = props;
// Generate a random ID once if missing
useEffect(() => {
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: 'mwai-reset-' + newId
});
}
}, [id]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_0__.AiBlockContainer, {
title: "Reset",
type: "reset",
isSelected: isSelected,
hint: /*#__PURE__*/React.createElement(React.Fragment, null, __('This block resets the AI form fields', 'ai-engine'))
}, __('ID:', 'ai-engine'), " ", id, /*#__PURE__*/React.createElement("br", null), __('Label:', 'ai-engine'), " ", label)), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: __('Reset Button Settings', 'ai-engine')
}, /*#__PURE__*/React.createElement(TextControl, {
label: __('ID', 'ai-engine'),
value: id,
onChange: value => setAttributes({
id: value
}),
help: __('Unique identifier. If omitted, one is auto-generated.', 'ai-engine')
}), /*#__PURE__*/React.createElement(TextControl, {
label: __('Label', 'ai-engine'),
value: label,
onChange: value => setAttributes({
label: value
}),
help: __('Text on the reset button.', 'ai-engine')
}), /*#__PURE__*/React.createElement(CheckboxControl, {
label: __('Local Memory', 'ai-engine'),
checked: localMemory,
onChange: value => setAttributes({
localMemory: value
}),
help: __('Clear local storage for this form’s key when resetting.', 'ai-engine')
}))));
};
/**
* Register the block
*/
const createResetBlock = () => {
registerBlockType('ai-engine/form-reset', {
title: 'AI Form Reset',
description: 'A reset button for your AI Form.',
icon: _common__WEBPACK_IMPORTED_MODULE_0__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form'), __('reset')],
supports: {
dimensions: {
minHeight: false
}
},
attributes: {
id: {
type: 'string',
default: ''
},
label: {
type: 'string',
default: 'Reset'
},
localMemory: {
type: 'boolean',
default: false
}
},
edit: FormResetBlock,
save: saveResetBlock
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createResetBlock);
/***/ }),
/***/ "./app/js/blocks/FormSubmitBlock.js":
/*!******************************************!*\
!*** ./app/js/blocks/FormSubmitBlock.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_components_TokensInfo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/components/TokensInfo */ "./app/js/components/TokensInfo.js");
// AI Engine
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useMemo,
useEffect
} = wp.element;
const {
PanelBody,
TextControl,
TextareaControl,
SelectControl,
CheckboxControl
} = wp.components;
const {
InspectorControls,
useBlockProps
} = wp.blockEditor;
const saveFormField = props => {
const {
attributes: {
id,
scope,
label,
prompt,
message,
outputElement,
aiEnvId,
embeddingsEnvId,
index,
namespace,
localMemory,
model,
temperature,
maxTokens,
isAssistant,
assistantId,
resolution
}
} = props;
const encodedPrompt = encodeURIComponent(prompt);
const encodedMessage = encodeURIComponent(message);
const blockProps = useBlockProps.save();
// Shortcode attributes
const shortcodeAttributes = {
id: {
value: id,
insertIfNull: true
},
scope: {
value: scope,
insertIfNull: false
},
local_memory: {
value: localMemory,
insertIfNull: false
},
label: {
value: label,
insertIfNull: true
},
prompt: {
value: encodedPrompt,
insertIfNull: false
},
message: {
value: encodedMessage,
insertIfNull: false
},
output_element: {
value: outputElement,
insertIfNull: true
},
model: {
value: model,
insertIfNull: false
},
temperature: {
value: temperature,
insertIfNull: false
},
max_tokens: {
value: maxTokens,
insertIfNull: false
},
is_assistant: {
value: isAssistant,
insertIfNull: false
},
env_id: {
value: aiEnvId,
insertIfNull: false
},
embeddings_env_id: {
value: embeddingsEnvId,
insertIfNull: false
},
embeddings_index: {
value: index,
insertIfNull: false
},
embeddings_namespace: {
value: namespace,
insertIfNull: false
},
assistant_id: {
value: assistantId,
insertIfNull: false
},
resolution: {
value: resolution,
insertIfNull: false
}
};
// Create the shortcode
let shortcode = Object.entries(shortcodeAttributes).filter(([, {
value,
insertIfNull
}]) => !!value || insertIfNull).reduce((acc, [key, {
value
}]) => `${acc} ${key}="${value}"`, "[mwai-form-submit");
shortcode = `${shortcode}]`;
// Return the shortcode
return /*#__PURE__*/React.createElement("div", blockProps, shortcode);
};
const FormSubmitBlock = props => {
var _currentModel$feature;
const blockProps = useBlockProps();
const {
attributes: {
id,
scope,
label,
message,
model,
temperature,
maxTokens,
aiEnvId,
embeddingsEnvId,
index,
namespace,
assistantId,
resolution,
isAssistant,
localMemory,
outputElement,
placeholders = []
},
setAttributes,
isSelected
} = props;
// Embeddings
const embeddingsEnvs = useMemo(() => _app_settings__WEBPACK_IMPORTED_MODULE_0__.options.embeddings_envs || [], []);
const embeddingsEnv = useMemo(() => {
const freshEnvironment = embeddingsEnvs.find(e => e.id === embeddingsEnvId) || null;
return freshEnvironment;
}, [embeddingsEnvs, embeddingsEnvId]);
const indexes = useMemo(() => (embeddingsEnv === null || embeddingsEnv === void 0 ? void 0 : embeddingsEnv.indexes) || [], [embeddingsEnv]);
const namespaces = useMemo(() => (embeddingsEnv === null || embeddingsEnv === void 0 ? void 0 : embeddingsEnv.namespaces) || [], [embeddingsEnv]);
// AI Environments
const aiEnvs = useMemo(() => _app_settings__WEBPACK_IMPORTED_MODULE_0__.options.ai_envs || [], []);
const {
models,
getModel
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(_app_settings__WEBPACK_IMPORTED_MODULE_0__.options, aiEnvId);
const currentModel = getModel(model);
const isImage = currentModel === null || currentModel === void 0 || (_currentModel$feature = currentModel.features) === null || _currentModel$feature === void 0 ? void 0 : _currentModel$feature.includes('text-to-image');
// AI Environment
const aiEnvironment = useMemo(() => {
const freshEnvironment = aiEnvs.find(e => e.id === aiEnvId) || null;
return freshEnvironment;
}, [aiEnvs, aiEnvId]);
// Assistants
const allAssistants = useMemo(() => (aiEnvironment === null || aiEnvironment === void 0 ? void 0 : aiEnvironment.assistants) || [], [aiEnvironment]);
const assistant = useMemo(() => {
const freshAssistant = allAssistants.find(e => e.id === assistantId) || null;
return freshAssistant;
}, [allAssistants, assistantId]);
// Reset the aiEnvId (and the rest) if the environment doesn't exist
useEffect(() => {
if ((aiEnvId || model) && !aiEnvironment) {
setAttributes({
aiEnvId: null,
model: null
});
}
}, [aiEnvId]);
// Reset the embeddingsEnvId (and the rest) if the environment doesn't exist
useEffect(() => {
if ((embeddingsEnvId || index || namespace) && !embeddingsEnv) {
setAttributes({
embeddingsEnvId: null,
index: null,
namespace: null
});
}
}, [embeddingsEnvId]);
// If there is an assistant, set the model to the assistant's model
useEffect(() => {
if (assistant && assistant.model && assistant.model !== model) {
setAttributes({
model: assistant.model
});
}
}, [assistant]);
// If the scope is null or empty, set it to 'form'
useEffect(() => {
if (!scope) {
setAttributes({
scope: 'form'
});
}
}, [scope]);
useEffect(() => {
if (!isAssistant) {
setAttributes({
assistantId: ''
});
}
}, [isAssistant]);
useEffect(() => {
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: 'mwai-' + newId
});
}
}, [id]);
useEffect(() => {
if (!aiEnvId && model !== "") {
setAttributes({
model: ""
});
}
}, [aiEnvId]);
useEffect(() => {
// Catch all the variables between the curly braces
const matches = message.match(/{([^}]+)}/g);
if (matches) {
const freshPlaceholders = matches.map(match => match.replace('{', '').replace('}', ''));
if (freshPlaceholders.join(',') !== placeholders.join(',')) {
setAttributes({
placeholders: freshPlaceholders
});
}
} else {
setAttributes({
placeholders: []
});
}
}, [message]);
const fieldsCount = useMemo(() => {
return placeholders ? placeholders.length : 0;
}, [placeholders]);
const assistantOptions = useMemo(() => {
const freshAssistants = allAssistants.map(assistant => ({
label: assistant.name,
value: assistant.id
}));
freshAssistants.unshift({
label: 'None',
value: ''
});
return freshAssistants;
}, [allAssistants]);
const modelOptions = useMemo(() => {
const freshModels = models.map(model => ({
label: model.rawName,
value: model.model
}));
freshModels.unshift({
label: 'Default',
value: ''
});
return freshModels;
}, [models]);
const resolutionOptions = useMemo(() => {
var _currentModel$resolut;
if (!currentModel || !isImage) {
return [];
}
const freshResolutions = (currentModel === null || currentModel === void 0 || (_currentModel$resolut = currentModel.resolutions) === null || _currentModel$resolut === void 0 ? void 0 : _currentModel$resolut.map(x => ({
label: x.label,
value: x.name
}))) || [];
freshResolutions.unshift({
label: 'None',
value: ''
});
return freshResolutions;
}, [currentModel, isImage]);
const indexOptions = useMemo(() => {
const freshIndexes = indexes.map(index => ({
label: index.name,
value: index.name
}));
freshIndexes.unshift({
label: 'None',
value: ''
});
return freshIndexes;
}, [indexes]);
const aiEnvironmentOptions = useMemo(() => {
const freshEnvironments = aiEnvs.map(env => ({
label: env.name,
value: env.id
}));
freshEnvironments.unshift({
label: 'Default',
value: ''
});
return freshEnvironments;
}, [aiEnvs]);
const embeddingsEnvironmentOptions = useMemo(() => {
const freshEnvironments = embeddingsEnvs.map(env => ({
label: env.name,
value: env.id
}));
freshEnvironments.unshift({
label: 'None',
value: ''
});
return freshEnvironments;
}, [embeddingsEnvs]);
const namespaceOptions = useMemo(() => {
const freshNamespaces = namespaces.map(namespace => ({
label: namespace,
value: namespace
}));
freshNamespaces.unshift({
label: 'None',
value: ''
});
return freshNamespaces;
}, [namespaces]);
const jsxFieldsCount = useMemo(() => {
if (fieldsCount === 0) {
return 'N/A';
}
return /*#__PURE__*/React.createElement("span", {
className: "mwai-pill"
}, fieldsCount, " field", fieldsCount > 1 ? 's' : '');
}, [fieldsCount]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_2__.AiBlockContainer, {
title: "Submit",
type: "submit",
isSelected: isSelected,
hint: /*#__PURE__*/React.createElement(React.Fragment, null, "IN:", ' ', /*#__PURE__*/React.createElement("span", {
className: "mwai-pill"
}, jsxFieldsCount), ' ', "OUT:", ' ', /*#__PURE__*/React.createElement("span", {
className: "mwai-pill mwai-pill-purple"
}, outputElement ? outputElement : "N/A"))
}, "Input Fields: ", placeholders.join(', '), /*#__PURE__*/React.createElement("br", null), "Prompt: ", message, /*#__PURE__*/React.createElement("br", null), "Output Element: ", outputElement)), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.OUTPUT
}, /*#__PURE__*/React.createElement(TextControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.LABEL,
value: label,
onChange: value => setAttributes({
label: value
})
}), /*#__PURE__*/React.createElement(TextareaControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PROMPT,
value: message,
onChange: value => setAttributes({
message: value
}),
help: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].FORMS.PROMPT_INFO
}), /*#__PURE__*/React.createElement(TextControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].FORMS.OUTPUT_ELEMENT,
value: outputElement,
onChange: value => setAttributes({
outputElement: value
}),
help: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].FORMS.OUTPUT_ELEMENT_INFO
})), /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL_PARAMS
}, aiEnvs && aiEnvs.length > 0 && /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT,
value: aiEnvId,
options: aiEnvironmentOptions,
onChange: value => setAttributes({
aiEnvId: value
})
}), aiEnvs && aiEnvs.length > 0 && /*#__PURE__*/React.createElement(CheckboxControl, {
label: "Assistant Mode",
checked: isAssistant,
onChange: value => setAttributes({
isAssistant: value
})
}), isAssistant && allAssistants && allAssistants.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ASSISTANT,
value: assistantId,
options: assistantOptions,
onChange: value => setAttributes({
assistantId: value
})
})), !isAssistant && /*#__PURE__*/React.createElement(React.Fragment, null, models && models.length > 0 && /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL,
value: model,
options: modelOptions,
disabled: !aiEnvId,
onChange: value => setAttributes({
model: value
})
}), !isImage && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TextControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.TEMPERATURE,
value: temperature,
onChange: value => setAttributes({
temperature: parseFloat(value)
}),
type: "number",
step: "0.1",
min: "0",
max: "1",
help: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.TEMPERATURE
}), /*#__PURE__*/React.createElement(TextControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MAX_TOKENS,
value: maxTokens,
onChange: value => setAttributes({
maxTokens: parseInt(value)
}),
type: "number",
step: "16",
min: "32",
max: "4096",
help: /*#__PURE__*/React.createElement(_app_components_TokensInfo__WEBPACK_IMPORTED_MODULE_4__["default"], {
model: currentModel,
maxTokens: maxTokens,
onRecommendedClick: value => setAttributes({
maxTokens: value
})
})
})), isImage && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.RESOLUTION,
value: resolution,
options: resolutionOptions,
onChange: value => setAttributes({
resolution: value
})
})))), !isImage && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CONTEXT_PARAMS
}, embeddingsEnvs && embeddingsEnvs.length > 0 && /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.EMBEDDINGS_ENV,
value: embeddingsEnvId,
options: embeddingsEnvironmentOptions,
disabled: !(embeddingsEnvironmentOptions !== null && embeddingsEnvironmentOptions !== void 0 && embeddingsEnvironmentOptions.length),
onChange: value => setAttributes({
embeddingsEnvId: value
})
}), indexes && indexes.length > 0 && /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.EMBEDDINGS_INDEX,
value: index,
options: indexOptions,
disabled: !(embeddingsEnvironmentOptions !== null && embeddingsEnvironmentOptions !== void 0 && embeddingsEnvironmentOptions.length),
onChange: value => setAttributes({
index: value
})
}), (embeddingsEnv === null || embeddingsEnv === void 0 ? void 0 : embeddingsEnv.type) === 'pinecone' && namespaces && namespaces.length > 0 && /*#__PURE__*/React.createElement(SelectControl, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.NAMESPACE,
value: namespace,
options: namespaceOptions,
disabled: !(embeddingsEnvironmentOptions !== null && embeddingsEnvironmentOptions !== void 0 && embeddingsEnvironmentOptions.length),
onChange: value => setAttributes({
namespace: value
})
}))), /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SYSTEM
}, /*#__PURE__*/React.createElement(TextControl, {
label: "ID",
value: id,
onChange: value => setAttributes({
id: value
})
}), /*#__PURE__*/React.createElement(CheckboxControl, {
label: "Local Memory",
checked: localMemory,
onChange: value => setAttributes({
localMemory: value
}),
help: "Store the forms data in the browser's local storage for 12 hours."
}), /*#__PURE__*/React.createElement(TextControl, {
label: "Scope",
value: scope,
onChange: value => setAttributes({
scope: value
}),
help: "The scope of the form. Different forms can have the same scope."
}))));
};
const createSubmitBlock = () => {
registerBlockType('ai-engine/form-submit', {
title: 'AI Form Submit',
description: 'The Submit Button for your AI Form.',
icon: _common__WEBPACK_IMPORTED_MODULE_2__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form')],
supports: {
dimensions: {
minHeight: false
}
},
attributes: {
id: {
type: 'string',
default: ''
},
scope: {
type: 'string',
default: 'form'
},
localMemory: {
type: 'boolean',
default: false
},
label: {
type: 'string',
default: 'Submit'
},
prompt: {
type: 'string',
default: ''
},
message: {
type: 'string',
default: ''
},
outputElement: {
type: 'string',
default: ''
},
model: {
type: 'string',
default: ''
},
temperature: {
type: 'number',
default: 0.8
},
maxTokens: {
type: 'number',
default: 4096
},
placeholders: {
type: 'array',
default: []
},
aiEnvId: {
type: 'string',
default: ''
},
embeddingsEnvId: {
type: 'string',
default: ''
},
index: {
type: 'string',
default: ''
},
namespace: {
type: 'string',
default: null
},
isAssistant: {
type: 'boolean',
default: false
},
assistantId: {
type: 'string',
default: ''
},
resolution: {
type: 'string',
default: null
}
},
edit: FormSubmitBlock,
save: saveFormField
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createSubmitBlock);
/***/ }),
/***/ "./app/js/blocks/FormUploadBlock.js":
/*!******************************************!*\
!*** ./app/js/blocks/FormUploadBlock.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./common */ "./app/js/blocks/common.js");
/**
* UploadFieldBlock.js
*/
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
useEffect
} = wp.element;
const {
Button,
PanelBody,
TextControl,
SelectControl,
CheckboxControl
} = wp.components;
const {
useBlockProps,
InspectorControls
} = wp.blockEditor;
/**
* Convert the selected accept type (all-images, all-documents, all, custom)
* into the actual MIME string or extension list for the <input>.
*/
function resolveAcceptValue(accept, customAccept) {
switch (accept) {
case 'all-images':
return 'image/*';
case 'all-documents':
// Adjust if you need additional formats
return '.pdf,.doc,.docx,.txt,.xls,.xlsx';
case 'all':
// Accept any file
return '';
case 'custom':
// The user’s custom input, e.g. ".png,.jpg"
return customAccept || '';
default:
return '';
}
}
/**
* Saves (front-end) => Generate the shortcode for output
*/
const saveUploadField = props => {
const {
attributes: {
id,
label,
name,
required,
accept,
customAccept,
multiple
}
} = props;
const blockProps = useBlockProps.save();
// Convert the user selection into the actual accept value
const resolvedAccept = resolveAcceptValue(accept, customAccept);
// Build shortcode
let shortcode = '[mwai-form-upload';
if (id) {
shortcode += ` id="${id}"`;
}
if (label) {
shortcode += ` label="${label}"`;
}
if (name) {
shortcode += ` name="${name}"`;
}
// only add accept if there's a meaningful value (empty string means any file)
if (resolvedAccept !== '') {
shortcode += ` accept="${resolvedAccept}"`;
}
if (multiple) {
shortcode += ` multiple="true"`;
}
if (required) {
shortcode += ` required="true"`;
}
shortcode += ']';
return /*#__PURE__*/React.createElement("div", blockProps, shortcode);
};
/**
* Edit (admin side) => the block’s sidebar settings + preview
*/
const UploadFieldBlock = props => {
const {
attributes: {
id,
label,
name,
required,
accept,
customAccept,
multiple
},
setAttributes,
isSelected
} = props;
const blockProps = useBlockProps();
useEffect(() => {
// Auto-generate an ID if not present
if (!id) {
const newId = Math.random().toString(36).substr(2, 9);
setAttributes({
id: 'mwai-' + newId
});
}
}, [id]);
const onUpdateLabel = value => {
setAttributes({
label: value
});
if (!name || name === 'LABEL') {
// Try to generate a name from the label
const newName = value.trim().replace(/ /g, '_').replace(/[^\w-]+/g, '').toUpperCase();
if (newName) {
setAttributes({
name: newName
});
}
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", blockProps, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_0__.AiBlockContainer, {
title: "Upload Field",
type: "field",
isSelected: isSelected,
hint: /*#__PURE__*/React.createElement("span", {
className: "mwai-pill"
}, '{' + name + '}')
}, /*#__PURE__*/React.createElement("div", null, label), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement("div", null, name))), /*#__PURE__*/React.createElement(InspectorControls, null, /*#__PURE__*/React.createElement(PanelBody, {
title: __('Upload Field Settings')
}, /*#__PURE__*/React.createElement(TextControl, {
label: "Label Text",
value: label,
onChange: onUpdateLabel
}), /*#__PURE__*/React.createElement(TextControl, {
label: "Field Name",
value: name,
onChange: value => setAttributes({
name: value
})
}), /*#__PURE__*/React.createElement(SelectControl, {
label: "Accept",
value: accept,
onChange: value => setAttributes({
accept: value
}),
options: [{
label: 'All Images',
value: 'all-images'
}, {
label: 'All Documents',
value: 'all-documents'
}, {
label: 'Any Files',
value: 'all'
}, {
label: 'Custom',
value: 'custom'
}]
}), accept === 'custom' && /*#__PURE__*/React.createElement(TextControl, {
label: "Custom MIME Types",
help: "Comma-separated list (e.g. .png,.jpg)",
value: customAccept,
onChange: value => setAttributes({
customAccept: value
})
}), /*#__PURE__*/React.createElement(CheckboxControl, {
label: "Multiple",
checked: multiple,
onChange: value => setAttributes({
multiple: value
})
}), /*#__PURE__*/React.createElement(CheckboxControl, {
label: "Required",
checked: required,
onChange: value => setAttributes({
required: value
})
})), /*#__PURE__*/React.createElement(PanelBody, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.SYSTEM
}, /*#__PURE__*/React.createElement(TextControl, {
label: "ID",
value: id,
onChange: value => setAttributes({
id: value
})
}))));
};
/**
* Register the new block
*/
const createUploadFieldBlock = () => {
registerBlockType('ai-engine/upload-field', {
apiVersion: 3,
title: 'AI Upload Field',
description: 'A File Upload field for your AI Form.',
icon: _common__WEBPACK_IMPORTED_MODULE_0__.meowIcon,
category: 'layout',
keywords: [__('ai'), __('openai'), __('form'), __('upload')],
attributes: {
id: {
type: 'string',
default: ''
},
label: {
type: 'string',
default: 'Upload:'
},
name: {
type: 'string',
default: 'UPLOAD'
},
required: {
type: 'boolean',
default: false
},
accept: {
type: 'string',
default: 'all-images' // or 'all'
},
customAccept: {
type: 'string',
default: '.png,.jpg'
},
multiple: {
type: 'boolean',
default: false
}
},
edit: UploadFieldBlock,
save: saveUploadField
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createUploadFieldBlock);
/***/ }),
/***/ "./app/js/blocks/common.js":
/*!*********************************!*\
!*** ./app/js/blocks/common.js ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ AiBlockContainer: () => (/* binding */ AiBlockContainer),
/* harmony export */ meowIcon: () => (/* binding */ meowIcon)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/hooks.js");
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _styles_AiIcon__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../styles/AiIcon */ "./app/js/styles/AiIcon.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const meowIcon = /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_0__["default"], {
icon: "ai",
style: {
width: 20,
height: 20
}
});
const BlockContainer = styled_components__WEBPACK_IMPORTED_MODULE_1__["default"].div`
color: black;
display: flex;
flex-direction: column;
border: 1px solid black;
font-size: 15px;
box-sizing: content-box;
font-weight: 400;
font-size: 13px;
padding: 10px;
background: hsl(0deg 0% 100% / 75%);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
margin-bottom: 10px;
.mwai-title-container {
flex: inherit;
padding: 5px 0px 5px 10px;
display: flex;
align-items: center;
color: black;
font-weight: 600;
cursor: pointer;
.mwai-hint {
font-size: 10px;
font-weight: 400;
text-align: right;
flex: auto;
.mwai-pill {
background: var(--wp--preset--color--vivid-cyan-blue);
padding: 5px 10px;
border-radius: 8px;
color: white;
}
.mwai-pill-purple {
background: var(--wp--preset--color--vivid-purple);
}
.mwai-pill-red {
background: var(--wp--preset--color--vivid-red);
}
}
}
.mwai-block-container-content {
flex: auto;
padding: 10px;
display: flex;
flex-direction: column;
}
&.mwai-chatbot {
background: var(--neko-main-color);
.mwai-title-container {
color: white;
}
.mwai-block-container-content {
margin-top: 10px;
border-radius: 5px;
background: var(--neko-background-color);
}
}
&.is-selected {
}
`;
const AiBlockContainer = ({
children,
type = "",
title = "",
hint = "",
isSelected,
isDisplayed,
...rest
}) => {
const classes = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.useClasses)('mwai-block-container', `mwai-${type}`, {
'is-selected': isSelected,
'is-meow': true
});
return /*#__PURE__*/React.createElement(BlockContainer, _extends({
className: classes
}, rest), /*#__PURE__*/React.createElement("div", {
className: "mwai-title-container"
}, /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_0__["default"], {
icon: "ai",
style: {
width: 20,
height: 20
}
}), /*#__PURE__*/React.createElement("div", null, title), /*#__PURE__*/React.createElement("div", {
className: "mwai-hint"
}, hint)), (isSelected || isDisplayed) && /*#__PURE__*/React.createElement("div", {
className: "mwai-block-container-content"
}, children));
};
/***/ }),
/***/ "./app/js/blocks/index.js":
/*!********************************!*\
!*** ./app/js/blocks/index.js ***!
\********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ initChatbotBlocks: () => (/* binding */ initChatbotBlocks),
/* harmony export */ initFormsBlocks: () => (/* binding */ initFormsBlocks)
/* harmony export */ });
/* harmony import */ var _ChatbotBlock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ChatbotBlock */ "./app/js/blocks/ChatbotBlock.js");
/* harmony import */ var _DiscussionsBlock__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./DiscussionsBlock */ "./app/js/blocks/DiscussionsBlock.js");
/* harmony import */ var _FormContainerBlock__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./FormContainerBlock */ "./app/js/blocks/FormContainerBlock.js");
/* harmony import */ var _FormFieldBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FormFieldBlock */ "./app/js/blocks/FormFieldBlock.js");
/* harmony import */ var _FormUploadBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./FormUploadBlock */ "./app/js/blocks/FormUploadBlock.js");
/* harmony import */ var _FormOutputBlock__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./FormOutputBlock */ "./app/js/blocks/FormOutputBlock.js");
/* harmony import */ var _FormSubmitBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./FormSubmitBlock */ "./app/js/blocks/FormSubmitBlock.js");
/* harmony import */ var _FormResetBlock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./FormResetBlock */ "./app/js/blocks/FormResetBlock.js");
/* harmony import */ var _FormConditionalBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./FormConditionalBlock */ "./app/js/blocks/FormConditionalBlock.js");
// The Storybook for Gutenberg
// https://wordpress.github.io/gutenberg
const initFormsBlocks = () => {
(0,_FormFieldBlock__WEBPACK_IMPORTED_MODULE_0__["default"])();
(0,_FormUploadBlock__WEBPACK_IMPORTED_MODULE_1__["default"])();
(0,_FormOutputBlock__WEBPACK_IMPORTED_MODULE_2__["default"])();
(0,_FormSubmitBlock__WEBPACK_IMPORTED_MODULE_3__["default"])();
(0,_FormResetBlock__WEBPACK_IMPORTED_MODULE_4__["default"])();
(0,_FormContainerBlock__WEBPACK_IMPORTED_MODULE_5__["default"])();
(0,_FormConditionalBlock__WEBPACK_IMPORTED_MODULE_6__["default"])();
};
const initChatbotBlocks = () => {
(0,_ChatbotBlock__WEBPACK_IMPORTED_MODULE_7__["default"])();
(0,_DiscussionsBlock__WEBPACK_IMPORTED_MODULE_8__["default"])();
};
/***/ }),
/***/ "./app/js/chatbot/AudioVisualizer.js":
/*!*******************************************!*\
!*** ./app/js/chatbot/AudioVisualizer.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ AudioVisualizerTwoStreams)
/* harmony export */ });
/**
* AudioVisualizerTwoStreams.jsx
*
* Two circles for user + assistant with volume-based pulsing.
* Each circle is inside a container of fixed size (circleSize + pulseMaxSize),
* so we don't affect overall layout when the ring expands.
*
* Outer ring has class "mwai-animation" to be styled or animated by your CSS.
* If userColor / assistantColor is null, we do NOT inline a color.
*/
// React & Vendor Libs
const {
useState,
useRef,
useEffect
} = wp.element;
/**
* measureVolume()
* Reads time-domain data and calculates an RMS volume (~0..~20 typical).
*/
function measureVolume(analyser, dataArray) {
analyser.getByteTimeDomainData(dataArray);
let sum = 0;
for (let i = 0; i < dataArray.length; i++) {
const val = dataArray[i] - 128;
sum += val * val;
}
return Math.sqrt(sum / dataArray.length); // RMS
}
function AudioVisualizerTwoStreams({
// Streams
assistantStream = null,
userStream = null,
// Colors for the circles
// If null, we don't apply inline color (you can do it via CSS)
assistantColor = null,
userColor = null,
// UI representations
// e.g. { emoji: "😊", text: "User", image: "url", use: "image" }
userUI = {
emoji: null,
text: null,
image: null,
use: "text"
},
assistantUI = {
emoji: null,
text: null,
image: null,
use: "text"
},
// Attack/Release speeds
attackSpeed = 0.3,
releaseSpeed = 0.05,
// Circle sizing
circleSize = 50,
// base diameter (inner circle)
pulseMaxSize = 30 // how many extra px to grow at max volume
}) {
// Smoothed volumes (state) for rendering
const [assistantVolume, setAssistantVolume] = useState(0);
const [userVolume, setUserVolume] = useState(0);
// We keep references to the raw volumes for attack/release
const assistantSmoothedRef = useRef(0);
const userSmoothedRef = useRef(0);
// AudioContext + Analyser
const audioContextRef = useRef(null);
const assistantAnalyserRef = useRef(null);
const assistantDataArrayRef = useRef(null);
const userAnalyserRef = useRef(null);
const userDataArrayRef = useRef(null);
useEffect(() => {
// If no streams, do nothing
if (!assistantStream && !userStream) {
return;
}
// Create or reuse AudioContext
if (!audioContextRef.current) {
audioContextRef.current = new AudioContext();
}
const audioContext = audioContextRef.current;
let assistantSource;
let userSource;
let animationFrameId;
// Setup assistant audio
if (assistantStream) {
assistantSource = audioContext.createMediaStreamSource(assistantStream);
assistantAnalyserRef.current = audioContext.createAnalyser();
assistantAnalyserRef.current.fftSize = 1024;
assistantDataArrayRef.current = new Uint8Array(assistantAnalyserRef.current.frequencyBinCount);
assistantSource.connect(assistantAnalyserRef.current);
}
// Setup user audio
if (userStream) {
userSource = audioContext.createMediaStreamSource(userStream);
userAnalyserRef.current = audioContext.createAnalyser();
userAnalyserRef.current.fftSize = 1024;
userDataArrayRef.current = new Uint8Array(userAnalyserRef.current.frequencyBinCount);
userSource.connect(userAnalyserRef.current);
}
// Animation loop
const tick = () => {
let newAssistantVolume = 0;
if (assistantAnalyserRef.current && assistantDataArrayRef.current) {
newAssistantVolume = measureVolume(assistantAnalyserRef.current, assistantDataArrayRef.current);
}
let newUserVolume = 0;
if (userAnalyserRef.current && userDataArrayRef.current) {
newUserVolume = measureVolume(userAnalyserRef.current, userDataArrayRef.current);
}
// Attack/release for assistant
if (newAssistantVolume > assistantSmoothedRef.current) {
// Attack
assistantSmoothedRef.current = assistantSmoothedRef.current * (1 - attackSpeed) + newAssistantVolume * attackSpeed;
} else {
// Release
assistantSmoothedRef.current = assistantSmoothedRef.current * (1 - releaseSpeed) + newAssistantVolume * releaseSpeed;
}
// Attack/release for user
if (newUserVolume > userSmoothedRef.current) {
// Attack
userSmoothedRef.current = userSmoothedRef.current * (1 - attackSpeed) + newUserVolume * attackSpeed;
} else {
// Release
userSmoothedRef.current = userSmoothedRef.current * (1 - releaseSpeed) + newUserVolume * releaseSpeed;
}
// Update state
setAssistantVolume(assistantSmoothedRef.current);
setUserVolume(userSmoothedRef.current);
// Next frame
animationFrameId = requestAnimationFrame(tick);
};
tick();
// Cleanup
return () => {
if (assistantSource) assistantSource.disconnect();
if (assistantAnalyserRef.current) assistantAnalyserRef.current.disconnect();
if (userSource) userSource.disconnect();
if (userAnalyserRef.current) userAnalyserRef.current.disconnect();
if (animationFrameId) cancelAnimationFrame(animationFrameId);
};
}, [assistantStream, userStream, attackSpeed, releaseSpeed]);
// Convert volumes ~0..20 to [0..1]
const normAssistant = Math.min(assistantVolume / 20, 1);
const normUser = Math.min(userVolume / 20, 1);
// Outer ring diameter = base circleSize + extra pulse
const assistantPulseDiameter = circleSize + normAssistant * pulseMaxSize;
const userPulseDiameter = circleSize + normUser * pulseMaxSize;
// The container is always big enough for the max ring
const containerSize = circleSize + pulseMaxSize; // e.g. 50 + 30 = 80
// If userColor/assistantColor is null, skip inline styling for backgroundColor
const userPulseStyle = {
width: userPulseDiameter,
height: userPulseDiameter,
borderRadius: "50%",
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
opacity: 0.5
};
if (userColor) {
userPulseStyle.backgroundColor = userColor;
}
const assistantPulseStyle = {
width: assistantPulseDiameter,
height: assistantPulseDiameter,
borderRadius: "50%",
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
opacity: 0.5
};
if (assistantColor) {
assistantPulseStyle.backgroundColor = assistantColor;
}
const userCircleStyle = {
width: circleSize,
height: circleSize,
borderRadius: "50%",
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
display: "flex",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
color: "#fff"
};
if (userColor) {
userCircleStyle.backgroundColor = userColor;
}
const assistantCircleStyle = {
width: circleSize,
height: circleSize,
borderRadius: "50%",
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
display: "flex",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
color: "#fff"
};
if (assistantColor) {
assistantCircleStyle.backgroundColor = assistantColor;
}
// Determine who is "talking"
let containerClass = "mwai-visualizer";
if (userVolume > assistantVolume) {
containerClass += " mwai-user-talking";
} else if (assistantVolume > userVolume) {
containerClass += " mwai-assistant-talking";
}
// Renders the UI inside the fixed circle
const renderUI = uiObj => {
if (!uiObj) return null;
const {
emoji,
text,
image,
use
} = uiObj;
switch (use) {
case "emoji":
if (emoji) return /*#__PURE__*/React.createElement("span", null, emoji);
if (text) return /*#__PURE__*/React.createElement("span", null, text.slice(0, 1));
return null;
case "image":
if (image) {
return /*#__PURE__*/React.createElement("img", {
src: image,
alt: "",
style: {
width: "100%",
height: "100%",
borderRadius: "50%"
}
});
}
// fallback to emoji or first-letter
if (emoji) return /*#__PURE__*/React.createElement("span", null, emoji);
if (text) return /*#__PURE__*/React.createElement("span", null, text.slice(0, 1));
return null;
case "text":
default:
if (text) return /*#__PURE__*/React.createElement("span", null, text.slice(0, 1));
if (emoji) return /*#__PURE__*/React.createElement("span", null, emoji);
return null;
}
};
return /*#__PURE__*/React.createElement("div", {
className: containerClass
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-visualizer-user",
style: {
position: "relative",
width: containerSize,
height: containerSize,
overflow: "visible"
}
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-animation",
style: userPulseStyle
}), /*#__PURE__*/React.createElement("div", {
style: userCircleStyle
}, renderUI(userUI))), /*#__PURE__*/React.createElement("hr", {
className: "mwai-visualizer-line"
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-visualizer-assistant",
style: {
position: "relative",
width: containerSize,
height: containerSize,
overflow: "visible"
}
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-animation",
style: assistantPulseStyle
}), /*#__PURE__*/React.createElement("div", {
style: assistantCircleStyle
}, renderUI(assistantUI))));
}
/***/ }),
/***/ "./app/js/chatbot/ChatUploadIcon.js":
/*!******************************************!*\
!*** ./app/js/chatbot/ChatUploadIcon.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers */ "./app/js/chatbot/helpers.js");
// React & Vendor Libs
const {
useState,
useMemo,
useRef
} = wp.element;
const ChatUploadIcon = () => {
const css = (0,_helpers__WEBPACK_IMPORTED_MODULE_0__.useClasses)();
const {
state,
actions
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_1__.useChatbotContext)();
const {
uploadedFile,
busy,
imageUpload,
fileUpload,
fileSearch,
draggingType
} = state;
const {
onUploadFile
} = actions;
const [isHovering, setIsHovering] = useState(false);
const fileInputRef = useRef();
const hasUploadedFile = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.uploadedId;
const uploadEnabled = imageUpload || fileSearch || fileUpload;
const handleMouseEnter = () => setIsHovering(true);
const handleMouseLeave = () => setIsHovering(false);
const resetUpload = () => onUploadFile(null);
const handleClick = () => {
if (uploadedFile !== null && uploadedFile !== void 0 && uploadedFile.localFile) {
resetUpload();
return;
}
if (!busy) {
fileInputRef.current.click();
}
};
const handleFileChange = event => {
const file = event.target.files[0];
if (file) onUploadFile(file);
};
// Mock uploadedFile for testing
// const mockUploadedFile = {
// localFile: { type: 'image/png' },
// uploadedId: '123',
// uploadProgress: 83.39
// };
const file = uploadedFile;
const type = useMemo(() => {
if (file !== null && file !== void 0 && file.localFile) {
return file.localFile.type.startsWith('image/') ? 'image' : 'document';
}
return draggingType;
}, [file, draggingType]);
const imgClass = useMemo(() => {
let status = 'idle';
if (file !== null && file !== void 0 && file.uploadProgress) {
status = 'up';
} else if (draggingType) {
status = 'add';
} else if (isHovering && hasUploadedFile) {
status = 'del';
} else if (hasUploadedFile) {
status = 'ok';
} else if (isHovering && !hasUploadedFile) {
status = 'add';
}
const typeClass = type ? type.toLowerCase() : 'idle';
return `mwai-file-upload-icon mwai-${typeClass}-${status}`;
}, [type, file, draggingType, isHovering, hasUploadedFile]);
// Calculate the UploadProgress Value
const uploadProgress = useMemo(() => {
if (file !== null && file !== void 0 && file.uploadProgress) {
if (file.uploadProgress > 99) {
return 99;
}
return Math.round(file.uploadProgress);
}
return "";
}, [file]);
return uploadEnabled ? /*#__PURE__*/React.createElement("div", {
disabled: busy,
onClick: handleClick,
onMouseEnter: handleMouseEnter,
onMouseLeave: handleMouseLeave,
className: css('mwai-file-upload', {
'mwai-enabled': uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.uploadedId,
'mwai-busy': (uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.localFile) && !(uploadedFile !== null && uploadedFile !== void 0 && uploadedFile.uploadedId)
}),
style: {
cursor: busy ? 'default' : 'pointer'
}
}, /*#__PURE__*/React.createElement("div", {
className: imgClass
}, /*#__PURE__*/React.createElement("span", {
className: "mwai-file-upload-progress"
}, uploadProgress)), /*#__PURE__*/React.createElement("input", {
type: "file",
ref: fileInputRef,
onChange: handleFileChange,
style: {
display: 'none'
}
})) : null;
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatUploadIcon);
/***/ }),
/***/ "./app/js/chatbot/ChatbotBody.js":
/*!***************************************!*\
!*** ./app/js/chatbot/ChatbotBody.js ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var markdown_to_jsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! markdown-to-jsx */ "./node_modules/markdown-to-jsx/dist/index.modern.js");
/* harmony import */ var _app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _ChatbotInput__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ChatbotInput */ "./app/js/chatbot/ChatbotInput.js");
/* harmony import */ var _ChatbotSubmit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChatbotSubmit */ "./app/js/chatbot/ChatbotSubmit.js");
/* harmony import */ var _ChatUploadIcon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ChatUploadIcon */ "./app/js/chatbot/ChatUploadIcon.js");
/* harmony import */ var _ChatbotRealtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ChatbotRealtime */ "./app/js/chatbot/ChatbotRealtime.js");
/* harmony import */ var _ChatbotEvents__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ChatbotEvents */ "./app/js/chatbot/ChatbotEvents.js");
const {
useState,
useEffect,
useRef,
useMemo
} = wp.element;
const markdownOptions = {
overrides: {
a: {
props: {
target: "_blank"
}
}
}
};
const ChatbotBody = ({
conversationRef,
onScroll,
messageList,
jsxShortcuts,
jsxBlocks,
inputClassNames,
handleDrop,
handleDrag,
needsFooter,
needTools,
uploadIconPosition
}) => {
const {
state,
actions
} = (0,_app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.useChatbotContext)();
const {
debugMode,
eventLogs,
messages,
error,
isRealtime,
textCompliance,
chatbotInputRef,
isWindow
} = state;
const {
resetError
} = actions;
const [allStreamData, setAllStreamData] = useState([]);
const [clearedMessageIds, setClearedMessageIds] = useState(new Set());
const streamDataRef = useRef([]);
const lastMessageCountRef = useRef(0);
const [realtimeMessages, setRealtimeMessages] = useState([]);
// Reset clearedMessageIds when messages are cleared (new conversation)
useEffect(() => {
if (messages.length === 0 || messages.length === 1 && messages[0].role === 'assistant') {
setClearedMessageIds(new Set());
}
}, [messages]);
useEffect(() => {
// Collect all stream events from all messages (including realtime)
const newStreamData = [];
const allMessages = [...messages, ...realtimeMessages];
allMessages.forEach(message => {
// Skip messages that have been cleared
if (message.streamEvents && debugMode && !clearedMessageIds.has(message.id)) {
// Add all events from this message
message.streamEvents.forEach(event => {
newStreamData.push({
...event,
messageId: message.id
});
});
}
});
// DON'T overwrite if we're in realtime mode - preserve directly added events
if (!isRealtime) {
// Always update to show all events
streamDataRef.current = newStreamData;
setAllStreamData(newStreamData);
}
}, [messages, realtimeMessages, debugMode, isRealtime, clearedMessageIds]);
const handleClearStreamData = () => {
// Clear the allStreamData
setAllStreamData([]);
streamDataRef.current = [];
// Mark which message IDs have been cleared to prevent their events from reappearing
const clearedMessageIds = new Set();
[...messages, ...realtimeMessages].forEach(msg => {
if (msg.streamEvents) {
clearedMessageIds.add(msg.id);
}
});
setClearedMessageIds(clearedMessageIds);
};
return /*#__PURE__*/React.createElement("div", {
className: "mwai-body"
}, !isRealtime && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
ref: conversationRef,
className: "mwai-conversation",
onScroll: onScroll
}, messageList, jsxShortcuts), jsxBlocks, /*#__PURE__*/React.createElement("div", {
className: inputClassNames,
onClick: () => {
var _chatbotInputRef$curr;
return (_chatbotInputRef$curr = chatbotInputRef.current) === null || _chatbotInputRef$curr === void 0 ? void 0 : _chatbotInputRef$curr.focusInput();
},
onDrop: handleDrop,
onDragEnter: event => handleDrag(event, true),
onDragLeave: event => handleDrag(event, false),
onDragOver: event => handleDrag(event, true)
}, /*#__PURE__*/React.createElement(_ChatbotInput__WEBPACK_IMPORTED_MODULE_1__["default"], null), /*#__PURE__*/React.createElement(_ChatbotSubmit__WEBPACK_IMPORTED_MODULE_2__["default"], null))), isRealtime && /*#__PURE__*/React.createElement("div", {
className: "mwai-realtime"
}, /*#__PURE__*/React.createElement(_ChatbotRealtime__WEBPACK_IMPORTED_MODULE_3__["default"], {
onMessagesUpdate: setRealtimeMessages,
onStreamEvent: event => {
setAllStreamData(prev => [...prev, event]);
}
})), error && /*#__PURE__*/React.createElement("div", {
className: "mwai-error",
onClick: () => resetError()
}, /*#__PURE__*/React.createElement(markdown_to_jsx__WEBPACK_IMPORTED_MODULE_4__["default"], {
options: markdownOptions
}, error)), needsFooter && /*#__PURE__*/React.createElement("div", {
className: "mwai-footer"
}, needTools && /*#__PURE__*/React.createElement("div", {
className: "mwai-tools"
}, uploadIconPosition === 'mwai-tools' && /*#__PURE__*/React.createElement(_ChatUploadIcon__WEBPACK_IMPORTED_MODULE_5__["default"], null)), textCompliance && /*#__PURE__*/React.createElement("div", {
className: "mwai-compliance",
dangerouslySetInnerHTML: {
__html: textCompliance
}
})), eventLogs && /*#__PURE__*/React.createElement(_ChatbotEvents__WEBPACK_IMPORTED_MODULE_6__["default"], {
allStreamData: allStreamData,
debugMode: debugMode,
onClear: handleClearStreamData,
hasData: allStreamData.length > 0,
isWindow: isWindow
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotBody);
/***/ }),
/***/ "./app/js/chatbot/ChatbotContent.js":
/*!******************************************!*\
!*** ./app/js/chatbot/ChatbotContent.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var markdown_to_jsx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! markdown-to-jsx */ "./node_modules/markdown-to-jsx/dist/index.modern.js");
/* harmony import */ var _app_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers */ "./app/js/helpers.js");
const {
useMemo
} = wp.element;
// Display a clickable link with additional file information
const LinkContainer = ({
href,
children
}) => {
if (!href) {
return /*#__PURE__*/React.createElement("span", null, children);
}
const target = '_blank';
const isFile = String(children) === "Uploaded File";
if (isFile) {
const filename = href.split('/').pop();
return /*#__PURE__*/React.createElement("a", {
href: href,
target: target,
rel: "noopener noreferrer",
className: "mwai-filename"
}, /*#__PURE__*/React.createElement("span", null, "\u2713 ", filename));
}
return /*#__PURE__*/React.createElement("a", {
href: href,
target: target,
rel: "noopener noreferrer"
}, children);
};
const ChatbotContent = ({
message
}) => {
let content = message.content ?? "";
// Ensure this is enclosed markdown
const matches = (content.match(/```/g) || []).length;
if (matches % 2 !== 0) {
// if count is odd
content += "\n```"; // add ``` at the end
}
const markdownOptions = useMemo(() => {
const options = {
overrides: {
BlinkingCursor: {
component: _app_helpers__WEBPACK_IMPORTED_MODULE_0__.BlinkingCursor
},
a: {
component: LinkContainer
},
// Max width for images should be 300px
img: {
props: {
onError: e => {
const src = e.target.src;
const isImage = src.match(/\.(jpeg|jpg|gif|png)$/) !== null;
if (isImage) {
e.target.src = "https://placehold.co/600x200?text=Expired+Image";
return;
}
},
className: "mwai-image"
}
}
}
};
return options;
}, []);
const renderedContent = useMemo(() => {
let out = "";
try {
out = (0,markdown_to_jsx__WEBPACK_IMPORTED_MODULE_1__.compiler)(content, markdownOptions);
} catch (e) {
console.error("Crash in markdown-to-jsx! Reverting to plain text.", {
e,
content
});
out = content;
}
return out;
}, [content, markdownOptions]);
// If streaming, always show the blinking cursor
if (message.isStreaming) {
return /*#__PURE__*/React.createElement(React.Fragment, null, renderedContent, /*#__PURE__*/React.createElement(_app_helpers__WEBPACK_IMPORTED_MODULE_0__.BlinkingCursor, null));
}
return renderedContent;
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotContent);
/***/ }),
/***/ "./app/js/chatbot/ChatbotContext.js":
/*!******************************************!*\
!*** ./app/js/chatbot/ChatbotContext.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ ChatbotContextProvider: () => (/* binding */ ChatbotContextProvider),
/* harmony export */ useChatbotContext: () => (/* binding */ useChatbotContext)
/* harmony export */ });
/* harmony import */ var _app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/chatbot/MwaiAPI */ "./app/js/chatbot/MwaiAPI.js");
/* harmony import */ var _app_helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/helpers */ "./app/js/helpers.js");
/* harmony import */ var _app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/helpers/tokenManager */ "./app/js/helpers/tokenManager.js");
// React & Vendor Libs
const {
useContext,
createContext,
useState,
useMemo,
useEffect,
useCallback,
useRef
} = wp.element;
// AI Engine
const rawAiName = 'AI: ';
const rawUserName = 'User: ';
const ChatbotContext = createContext();
const useChatbotContext = () => {
const context = useContext(ChatbotContext);
if (!context) {
throw new Error('useChatbotContext must be used within a ChatbotContextProvider');
}
return context;
};
const ChatbotContextProvider = ({
children,
...rest
}) => {
var _params$startSentence;
const {
params,
system,
theme,
atts
} = rest;
const {
timeElapsed,
startChrono,
stopChrono
} = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.useChrono)();
const shortcodeStyles = useMemo(() => (theme === null || theme === void 0 ? void 0 : theme.settings) || {}, [theme]);
const [restNonce, setRestNonce] = useState(system.restNonce || _app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__["default"].getToken());
const restNonceRef = useRef(system.restNonce || _app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__["default"].getToken());
// Subscribe to global token updates
useEffect(() => {
const unsubscribe = _app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__["default"].subscribe(newToken => {
setRestNonce(newToken);
restNonceRef.current = newToken;
});
return unsubscribe;
}, []);
const [messages, setMessages] = useState([]);
const [shortcuts, setShortcuts] = useState([]);
const [blocks, setBlocks] = useState([]);
const [locked, setLocked] = useState(false);
const [chatId, setChatId] = useState((0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)());
const [inputText, setInputText] = useState('');
const [chatbotTriggered, setChatbotTriggered] = useState(false);
const [showIconMessage, setShowIconMessage] = useState(false);
const [uploadedFile, setUploadedFile] = useState({
localFile: null,
uploadedId: null,
uploadedUrl: null,
uploadProgress: null
});
const [windowed, setWindowed] = useState(true); // When fullscreen is enabled, minimize is the reduced version.
const [open, setOpen] = useState(false);
const [error, setError] = useState(null);
const [busy, setBusy] = useState(false);
const [busyNonce, setBusyNonce] = useState(false);
const [serverReply, setServerReply] = useState();
const [previousResponseId, setPreviousResponseId] = useState(null);
const chatbotInputRef = useRef();
const conversationRef = useRef();
const hasFocusRef = useRef(false);
const {
isListening,
setIsListening,
speechRecognitionAvailable
} = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.useSpeechRecognition)(text => {
setInputText(text);
});
// System Parameters
//const id = system.id;
const stream = system.stream || false;
const internalId = useMemo(() => (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)(), []);
const botId = system.botId;
const customId = system.customId;
const userData = system.userData;
const [sessionId, setSessionId] = useState(system.sessionId);
const contextId = system.contextId; // This is used by Content Aware (to retrieve a Post)
const pluginUrl = system.pluginUrl;
const restUrl = system.restUrl;
const debugMode = system.debugMode;
const eventLogs = system.eventLogs;
const virtualKeyboardFix = system.virtual_keyboard_fix;
const typewriter = (system === null || system === void 0 ? void 0 : system.typewriter) ?? false;
const speechRecognition = (system === null || system === void 0 ? void 0 : system.speech_recognition) ?? false;
const speechSynthesis = (system === null || system === void 0 ? void 0 : system.speech_synthesis) ?? false;
const startSentence = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.doPlaceholders)(((_params$startSentence = params.startSentence) === null || _params$startSentence === void 0 ? void 0 : _params$startSentence.trim()) ?? "", userData);
// Initial Actions, Shortcuts, and Blocks
const initialActions = system.actions || [];
const initialShortcuts = system.shortcuts || [];
const initialBlocks = system.blocks || [];
// UI Parameters
const isMobile = document.innerWidth <= 768;
const processedParams = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.processParameters)(params, userData);
const {
aiName,
userName,
guestName,
aiAvatar,
userAvatar,
guestAvatar
} = processedParams;
const {
textSend,
textClear,
textInputMaxLength,
textInputPlaceholder,
textCompliance,
window: isWindow,
copyButton,
headerSubtitle,
fullscreen,
localMemory: localMemoryParam,
icon,
iconText,
iconTextDelay,
iconAlt,
iconPosition,
iconBubble,
imageUpload,
fileUpload,
fileSearch
} = processedParams;
const isRealtime = processedParams.mode === 'realtime';
const localMemory = localMemoryParam && (!!customId || !!botId);
const localStorageKey = localMemory ? `mwai-chat-${customId || botId}` : null;
const {
cssVariables,
iconUrl,
aiAvatarUrl,
userAvatarUrl,
guestAvatarUrl
} = useMemo(() => {
const processUrl = url => {
if (!url) return null;
if ((0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.isEmoji)(url)) return url;
return (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.isURL)(url) ? url : `${pluginUrl}/images/${url}`;
};
const iconUrl = icon ? processUrl(icon) : `${pluginUrl}/images/chat-traditional-1.svg`;
const finalAiAvatarUrl = processUrl(processedParams.aiAvatarUrl);
const finalUserAvatarUrl = processUrl(processedParams.userAvatarUrl);
const finalGuestAvatarUrl = processUrl(processedParams.guestAvatarUrl);
const cssVariables = Object.keys(shortcodeStyles).reduce((acc, key) => {
acc[`--mwai-${key}`] = shortcodeStyles[key];
return acc;
}, {});
return {
cssVariables,
iconUrl,
aiAvatarUrl: finalAiAvatarUrl,
userAvatarUrl: finalUserAvatarUrl,
guestAvatarUrl: finalGuestAvatarUrl
};
}, [icon, pluginUrl, shortcodeStyles, processedParams]);
const [draggingType, setDraggingType] = useState(false);
// This is used to block the drop event when the file is not allowed:
const [isBlocked, setIsBlocked] = useState(false);
// Theme-Related Parameters
const uploadIconPosition = useMemo(() => {
if ((theme === null || theme === void 0 ? void 0 : theme.themeId) === 'timeless') {
return 'mwai-tools';
}
return "mwai-input";
}, [theme === null || theme === void 0 ? void 0 : theme.themeId]);
const submitButtonConf = useMemo(() => {
return {
text: textSend,
textSend: textSend,
textClear: textClear,
imageSend: (theme === null || theme === void 0 ? void 0 : theme.themeId) === 'timeless' ? pluginUrl + '/images/action-submit-blue.svg' : null,
imageClear: (theme === null || theme === void 0 ? void 0 : theme.themeId) === 'timeless' ? pluginUrl + '/images/action-clear-blue.svg' : null
//imageOnly: false,
};
}, [pluginUrl, textClear, textSend, theme === null || theme === void 0 ? void 0 : theme.themeId]);
const resetMessages = () => {
resetUploadedFile();
setPreviousResponseId(null); // Reset response ID when clearing messages
if (startSentence) {
const freshMessages = [{
id: (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)(),
role: 'assistant',
content: startSentence,
who: rawAiName,
timestamp: new Date().getTime()
}];
setMessages(freshMessages);
} else {
setMessages([]);
}
};
const refreshRestNonce = useCallback(async (force = false) => {
try {
if (!force && restNonce) {
return restNonce;
}
setBusyNonce(true);
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetch)(`${restUrl}/mwai/v1/start_session`);
const data = await res.json();
setRestNonce(data.restNonce);
restNonceRef.current = data.restNonce;
_app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__["default"].setToken(data.restNonce); // Update globally
// Update sessionId if it was N/A or different
if (data.sessionId && data.sessionId !== 'N/A') {
setSessionId(data.sessionId);
}
// Also update if new_token is present (in case of token test mode)
if (data.new_token) {
// Log token update with expiration info
if (data.token_expires_at) {
const expiresAt = new Date(data.token_expires_at * 1000);
console.log(`[MWAI] 🔐 New token received - expires at ${expiresAt.toLocaleTimeString()} (in ${data.token_expires_in}s)`);
}
setRestNonce(data.new_token);
restNonceRef.current = data.new_token;
_app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__["default"].setToken(data.new_token); // Update globally
return data.new_token;
}
return data.restNonce;
} catch (err) {
console.error('Error while fetching the restNonce.', err);
} finally {
setBusyNonce(false);
}
}, [restNonce, setRestNonce, restUrl, setSessionId]);
// Track if we're resuming an existing conversation
const [isResumingConversation, setIsResumingConversation] = useState(false);
const [isConversationLoaded, setIsConversationLoaded] = useState(false);
// Initialize the initialActions, initialShortcuts, and initialBlocks
useEffect(() => {
if (debugMode) {
// console.log('[INIT] Shortcuts init effect', {
// isConversationLoaded,
// isResumingConversation,
// messagesLength: messages.length,
// initialShortcutsLength: initialShortcuts.length
// });
}
// Wait until we've checked for existing conversation before initializing
if (!isConversationLoaded) {
return;
}
// Only show initial shortcuts if this is a new conversation
// Check both isResumingConversation flag and if we have existing messages (excluding start sentence)
const hasExistingConversation = isResumingConversation || messages.length > 1 || messages.length === 1 && messages[0].content !== startSentence;
if (!hasExistingConversation) {
if (debugMode) {
// console.log('[INIT] Showing initial shortcuts');
}
if (initialActions.length > 0) {
handleActions(initialActions);
}
if (initialShortcuts.length > 0) {
handleShortcuts(initialShortcuts);
}
if (initialBlocks.length > 0) {
handleBlocks(initialBlocks);
}
} else {
if (debugMode) {
// console.log('[INIT] NOT showing initial shortcuts - existing conversation');
}
}
}, [isConversationLoaded, isResumingConversation, messages, startSentence]);
// Initialized the restNonce
useEffect(() => {
if (chatbotTriggered && !restNonce) {
refreshRestNonce();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [chatbotTriggered]);
useEffect(() => {
if (inputText.length > 0 && !chatbotTriggered) {
setChatbotTriggered(true);
}
}, [chatbotTriggered, inputText]);
// Reset messages when the start sentence changes.
useEffect(() => {
resetMessages();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [startSentence]);
// Initializes the mwaiAPI (used to interact with the chatbot)
useEffect(() => {
if (customId || botId) {
const existingChatbotIndex = _app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__.mwaiAPI.chatbots.findIndex(chatbot => chatbot.internalId === internalId);
const chatbot = {
internalId: internalId,
// This is used to identify the chatbot in the current page.
botId: botId,
chatId: chatId,
customId: customId,
localStorageKey: localStorageKey,
// Add localStorageKey for discussion loading
open: () => {
setTasks(prevTasks => [...prevTasks, {
action: 'open'
}]);
},
close: () => {
setTasks(prevTasks => [...prevTasks, {
action: 'close'
}]);
},
clear: params => {
const {
chatId = null
} = params || {};
setTasks(prevTasks => [...prevTasks, {
action: 'clear',
data: {
chatId
}
}]);
},
toggle: () => {
setTasks(prevTasks => [...prevTasks, {
action: 'toggle'
}]);
},
ask: (text, submit = false) => {
setTasks(prevTasks => [...prevTasks, {
action: 'ask',
data: {
text,
submit
}
}]);
},
lock: () => {
setLocked(true);
},
unlock: () => {
setLocked(false);
},
setShortcuts: shortcuts => {
setTasks(prevTasks => [...prevTasks, {
action: 'setShortcuts',
data: shortcuts
}]);
},
setBlocks: blocks => {
setTasks(prevTasks => [...prevTasks, {
action: 'setBlocks',
data: blocks
}]);
},
addBlock: block => {
setTasks(prevTasks => [...prevTasks, {
action: 'addBlock',
data: block
}]);
},
removeBlockById: blockId => {
setTasks(prevTasks => [...prevTasks, {
action: 'removeBlockById',
data: blockId
}]);
},
getBlocks: () => {
return blocks;
},
setContext: ({
chatId,
messages,
previousResponseId
}) => {
console.warn('MwaiAPI: setContext is deprecated. Please use setConversation instead.');
setTasks(prevTasks => [...prevTasks, {
action: 'setContext',
data: {
chatId,
messages,
previousResponseId
}
}]);
},
setConversation: ({
chatId,
messages,
previousResponseId
}) => {
setTasks(prevTasks => [...prevTasks, {
action: 'setContext',
data: {
chatId,
messages,
previousResponseId
}
}]);
}
};
if (existingChatbotIndex !== -1) {
_app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__.mwaiAPI.chatbots[existingChatbotIndex] = chatbot;
} else {
_app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__.mwaiAPI.chatbots.push(chatbot);
}
}
}, [botId, chatId, customId, internalId, localStorageKey, blocks]);
// Starts the timer when the chatbot is busy
useEffect(() => {
var _chatbotInputRef$curr;
if (busy) {
startChrono();
return;
}
if (!isMobile && hasFocusRef.current && (_chatbotInputRef$curr = chatbotInputRef.current) !== null && _chatbotInputRef$curr !== void 0 && _chatbotInputRef$curr.focusInput) {
chatbotInputRef.current.focusInput();
}
stopChrono();
}, [busy, startChrono, stopChrono, isMobile]);
const saveMessages = useCallback(messages => {
if (!localStorageKey) {
return;
}
localStorage.setItem(localStorageKey, (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.nekoStringify)({
chatId: chatId,
messages: messages
}));
}, [localStorageKey, chatId]);
const resetError = () => {
setError(null);
};
// New BotId: Initializes the chat history
useEffect(() => {
let chatHistory = [];
if (localStorageKey) {
chatHistory = localStorage.getItem(localStorageKey);
if (chatHistory) {
chatHistory = JSON.parse(chatHistory);
setMessages(chatHistory.messages);
setChatId(chatHistory.chatId);
setIsResumingConversation(true);
setIsConversationLoaded(true);
return;
}
}
setIsResumingConversation(false);
setIsConversationLoaded(true);
resetMessages();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [botId]);
// Track executed actions to prevent double execution
const executedActionsRef = useRef(new Set());
const handleActions = useCallback((actions, lastMessage) => {
actions = actions || [];
let callsCount = 0;
for (const action of actions) {
if (action.type === 'function') {
const data = action.data || {};
const {
name = null,
args = []
} = data;
// Create a unique key for this action based on function name and arguments
const actionKey = `${name}_${JSON.stringify(args)}`;
// Check if this action was already executed recently
if (executedActionsRef.current.has(actionKey)) {
if (debugMode) {
console.log(`[CHATBOT] Skipping duplicate execution of ${name}`);
}
continue;
}
const finalArgs = args ? Object.values(args).map(arg => {
return JSON.stringify(arg);
}) : [];
try {
if (debugMode) {
// eslint-disable-next-line no-console
console.log(`[CHATBOT] CALL ${name}(${finalArgs.join(', ')})`);
}
// Mark as executed before calling to prevent race conditions
executedActionsRef.current.add(actionKey);
eval(`${name}(${finalArgs.join(', ')})`);
callsCount++;
// Clean up old entries after 5 seconds
setTimeout(() => {
executedActionsRef.current.delete(actionKey);
}, 5000);
} catch (err) {
console.error('Error while executing an action.', err);
// Remove from executed set if there was an error
executedActionsRef.current.delete(actionKey);
}
}
}
if (!lastMessage.content && callsCount > 0) {
lastMessage.content = `*Done!*`;
}
}, [debugMode]);
const handleShortcuts = useCallback(shortcuts => {
setShortcuts(shortcuts || []);
}, []);
const handleBlocks = useCallback(blocks => {
setBlocks(blocks || []);
}, []);
// New Server Reply: Update the messages
useEffect(() => {
if (!serverReply) {
return;
}
setBusy(false);
const freshMessages = [...messages];
const lastMessage = freshMessages.length > 0 ? freshMessages[freshMessages.length - 1] : null;
// Failure
if (!serverReply.success) {
// Get the user message before removing it to restore in input field
let userMessage = null;
// Remove the isQuerying placeholder for the assistant.
if (lastMessage.role === 'assistant' && lastMessage.isQuerying) {
freshMessages.pop();
}
// Get the user message before removing it
const userMessageIndex = freshMessages.length - 1;
if (userMessageIndex >= 0 && freshMessages[userMessageIndex].role === 'user') {
userMessage = freshMessages[userMessageIndex];
// Extract the actual text content without image/file markdown
const content = userMessage.content;
// Remove markdown image/file prefix if present
const markdownMatch = content.match(/^(?:\!\[.*?\]\(.*?\)|\[.*?\]\(.*?\))\n(.*)$/s);
const textToRestore = markdownMatch ? markdownMatch[1] : content;
// Restore the user's text in the input field
setInputText(textToRestore);
}
// Remove the user message.
freshMessages.pop();
// Add error message
freshMessages.push({
id: (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)(),
role: 'system',
content: serverReply.message,
who: rawAiName,
timestamp: new Date().getTime()
});
setMessages(freshMessages);
saveMessages(freshMessages);
return;
}
// Success: Let's update the isQuerying/isStreaming or add a new message.
if (lastMessage.role === 'assistant' && lastMessage.isQuerying) {
lastMessage.content = (0,_app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__.applyFilters)('ai.reply', serverReply.reply, {
chatId,
botId
});
if (serverReply.images) {
lastMessage.images = serverReply.images;
}
lastMessage.timestamp = new Date().getTime();
delete lastMessage.isQuerying;
handleActions(serverReply === null || serverReply === void 0 ? void 0 : serverReply.actions, lastMessage);
handleBlocks(serverReply === null || serverReply === void 0 ? void 0 : serverReply.blocks);
handleShortcuts(serverReply === null || serverReply === void 0 ? void 0 : serverReply.shortcuts);
} else if (lastMessage.role === 'assistant' && lastMessage.isStreaming) {
lastMessage.content = (0,_app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__.applyFilters)('ai.reply', serverReply.reply, {
chatId,
botId
});
if (serverReply.images) {
lastMessage.images = serverReply.images;
}
lastMessage.timestamp = new Date().getTime();
delete lastMessage.isStreaming;
// Add completion event for streaming
if (debugMode && lastMessage.streamEvents) {
var _lastMessage$streamEv;
const now = new Date().getTime();
const startTime = ((_lastMessage$streamEv = lastMessage.streamEvents[0]) === null || _lastMessage$streamEv === void 0 ? void 0 : _lastMessage$streamEv.timestamp) || now;
const duration = now - startTime;
// Format duration in human-readable format
let durationText;
if (duration < 1000) {
durationText = `${duration}ms`;
} else if (duration < 60000) {
durationText = `${(duration / 1000).toFixed(1)}s`;
} else {
const minutes = Math.floor(duration / 60000);
const seconds = (duration % 60000 / 1000).toFixed(0);
durationText = `${minutes}m ${seconds}s`;
}
lastMessage.streamEvents.push({
type: 'event',
subtype: 'status',
data: `Request completed in ${durationText}.`,
timestamp: now
});
}
handleActions(serverReply === null || serverReply === void 0 ? void 0 : serverReply.actions, lastMessage);
handleBlocks(serverReply === null || serverReply === void 0 ? void 0 : serverReply.blocks);
handleShortcuts(serverReply === null || serverReply === void 0 ? void 0 : serverReply.shortcuts);
}
// Otherwise, let's add a new message
else {
const newMessage = {
id: (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)(),
role: 'assistant',
content: (0,_app_chatbot_MwaiAPI__WEBPACK_IMPORTED_MODULE_3__.applyFilters)('ai.reply', serverReply.reply, {
botId,
chatId,
customId
}),
who: rawAiName,
timestamp: new Date().getTime()
};
if (serverReply.images) {
newMessage.images = serverReply.images;
}
handleActions(serverReply === null || serverReply === void 0 ? void 0 : serverReply.actions, newMessage);
handleBlocks(serverReply === null || serverReply === void 0 ? void 0 : serverReply.blocks);
handleShortcuts(serverReply === null || serverReply === void 0 ? void 0 : serverReply.shortcuts);
freshMessages.push(newMessage);
}
// Store response ID if available (for Responses API)
if (serverReply.responseId) {
setPreviousResponseId(serverReply.responseId);
}
setMessages(freshMessages);
saveMessages(freshMessages);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [serverReply]);
// #region Submit Actions (Clear, Submit, File Upload, etc.)
const onClear = useCallback(async ({
chatId = null
} = {}) => {
if (!chatId) {
chatId = (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)();
}
await setChatId(chatId);
if (localStorageKey) {
localStorage.removeItem(localStorageKey);
}
resetMessages();
setInputText('');
// Mark as not resuming since we're starting fresh
setIsResumingConversation(false);
setIsConversationLoaded(true);
// Restore initial shortcuts instead of clearing them
if (initialShortcuts.length > 0) {
handleShortcuts(initialShortcuts);
} else {
setShortcuts([]);
}
setBlocks([]);
setPreviousResponseId(null); // Reset response ID on clear
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [botId, initialShortcuts, handleShortcuts]);
const onStartRealtimeSession = useCallback(async () => {
const body = {
botId: botId,
customId: customId,
contextId: contextId,
chatId: chatId
};
const nonce = restNonceRef.current ?? (await refreshRestNonce());
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetch)(`${restUrl}/mwai-ui/v1/openai/realtime/start`, body, nonce);
const data = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiHandleRes)(res, null, null, null, debugMode);
return data;
}, [botId, customId, contextId, chatId, restNonce, refreshRestNonce, restUrl]);
const onCommitStats = useCallback(async (stats, refId = null) => {
try {
const nonce = restNonceRef.current ?? (await refreshRestNonce());
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetch)(`${restUrl}/mwai-ui/v1/openai/realtime/stats`, {
botId: botId,
session: sessionId,
refId: refId || chatId,
stats: stats
}, nonce);
const data = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiHandleRes)(res, null, null, null, debugMode);
return {
success: data.success,
message: data.message,
overLimit: data.overLimit || false,
limitMessage: data.limitMessage || null
};
} catch (err) {
console.error('Error while committing stats.', err);
return {
success: false,
message: 'An error occurred while committing the stats.'
};
}
}, [botId, restNonce, refreshRestNonce, restUrl, sessionId, chatId]);
const onCommitDiscussions = useCallback(async (messages = []) => {
try {
const nonce = restNonceRef.current ?? (await refreshRestNonce());
const payload = {
botId: botId,
session: sessionId,
chatId: chatId,
messages: messages ?? []
};
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetch)(`${restUrl}/mwai-ui/v1/openai/realtime/discussions`, payload, nonce);
const data = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiHandleRes)(res, null, null, null, debugMode);
return {
success: data.success,
message: data.message
};
} catch (err) {
console.error('Error while committing discussion.', err);
return {
success: false,
message: 'An error occurred while committing the discussion.'
};
}
}, [botId, chatId, restNonce, refreshRestNonce, restUrl, sessionId]);
const onRealtimeFunctionCallback = useCallback(async (functionId, functionType, functionName, functionTarget, args) => {
const body = {
functionId,
functionType,
functionName,
functionTarget,
arguments: args
};
if (functionTarget === 'js') {
const finalArgs = args ? Object.values(args).map(arg => {
return JSON.stringify(arg);
}) : [];
try {
if (debugMode) {
// eslint-disable-next-line no-console
console.log(`[CHATBOT] CALL ${functionName}(${finalArgs.join(', ')})`);
}
eval(`${functionName}(${finalArgs.join(', ')})`);
return {
success: true,
message: 'The function was executed',
data: null
};
} catch (err) {
console.error('Error while executing an action.', err);
return {
success: false,
message: 'An error occurred while executing the function.',
data: null
};
}
} else {
const nonce = restNonceRef.current ?? (await refreshRestNonce());
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetch)(`${restUrl}/mwai-ui/v1/openai/realtime/call`, body, nonce);
const data = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiHandleRes)(res, null, null, null, debugMode);
return data;
}
return null;
}, [restNonce, refreshRestNonce, restUrl, debugMode]);
const onSubmit = useCallback(async textQuery => {
var _uploadedFile$localFi;
if (busy) {
console.error('AI Engine: There is already a query in progress.');
return;
}
// This avoid the onSubmit to send an event.
if (typeof textQuery !== 'string') {
textQuery = inputText;
}
const currentFile = uploadedFile;
const currentImageUrl = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.uploadedUrl;
const mimeType = uploadedFile === null || uploadedFile === void 0 || (_uploadedFile$localFi = uploadedFile.localFile) === null || _uploadedFile$localFi === void 0 ? void 0 : _uploadedFile$localFi.type;
const isImage = mimeType ? mimeType.startsWith('image') : false;
// textQuery is the text that will be sent to AI
// but we also need the text that will be displayed in the chat, with the uploaded image first, using Markdown
let textDisplay = textQuery;
if (currentImageUrl) {
if (isImage) {
textDisplay = `\n${textQuery}`;
} else {
textDisplay = `[Uploaded File](${currentImageUrl})\n${textQuery}`;
}
}
setBusy(true);
setInputText('');
setShortcuts([]);
setBlocks([]);
resetUploadedFile();
const bodyMessages = [...messages, {
id: (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)(),
role: 'user',
content: textDisplay,
who: rawUserName,
timestamp: new Date().getTime()
}];
saveMessages(bodyMessages);
const freshMessageId = (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.randomStr)();
const freshMessages = [...bodyMessages, {
id: freshMessageId,
role: 'assistant',
content: stream ? '' : null,
who: rawAiName,
timestamp: null,
isQuerying: stream ? false : true,
isStreaming: stream ? true : false,
// Add initial stream event for request start
streamEvents: stream && debugMode ? [] : undefined
}];
setMessages(freshMessages);
const body = {
botId: botId,
customId: customId,
session: sessionId,
chatId: chatId,
contextId: contextId,
messages: messages,
newMessage: textQuery,
newFileId: currentFile === null || currentFile === void 0 ? void 0 : currentFile.uploadedId,
stream,
...atts
};
// Add previousResponseId if available (for Responses API)
if (previousResponseId) {
body.previousResponseId = previousResponseId;
}
try {
if (debugMode) {
// eslint-disable-next-line no-console
console.log('[CHATBOT] OUT: ', body);
}
const streamCallback = !stream ? null : (content, streamData) => {
// Debug enhanced streaming data
if (debugMode && streamData && streamData.subtype) {
console.log('[CHATBOT] STREAM EVENT:', streamData);
}
setMessages(messages => {
const freshMessages = [...messages];
const lastMessage = freshMessages.length > 0 ? freshMessages[freshMessages.length - 1] : null;
if (lastMessage && lastMessage.id === freshMessageId) {
lastMessage.content = content;
lastMessage.timestamp = new Date().getTime();
// Store stream data for enhanced display
if (streamData && streamData.subtype) {
// Initialize streamEvents array if not exists
if (!lastMessage.streamEvents) {
lastMessage.streamEvents = [];
}
// Add the new event with timestamp
lastMessage.streamEvents.push({
...streamData,
timestamp: new Date().getTime()
});
}
}
return freshMessages;
});
};
// We need to refresh the restNonce before sending the request.
const nonce = restNonceRef.current ?? (await refreshRestNonce());
// Send "Request sent..." event immediately when we send the HTTP request
if (stream && debugMode && streamCallback) {
streamCallback('', {
type: 'event',
subtype: 'status',
data: 'Request sent...',
timestamp: new Date().getTime()
});
}
// Handler for token updates
const handleTokenUpdate = newToken => {
setRestNonce(newToken);
restNonceRef.current = newToken;
_app_helpers_tokenManager__WEBPACK_IMPORTED_MODULE_1__["default"].setToken(newToken); // Update globally
};
// Let's perform the request. The mwaiHandleRes will handle the complexity of response.
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetch)(`${restUrl}/mwai-ui/v1/chats/submit`, body, nonce, stream, undefined, handleTokenUpdate);
const data = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiHandleRes)(res, streamCallback, debugMode ? "CHATBOT" : null, handleTokenUpdate, debugMode);
if (!data.success && data.message) {
setError(data.message);
// We remove the two last messages (the query, and the 'busy' message).
const updatedMessages = [...freshMessages];
updatedMessages.pop(); // Remove assistant message
// Get the user message before removing it to restore in input field
const userMessageIndex = updatedMessages.length - 1;
if (userMessageIndex >= 0 && updatedMessages[userMessageIndex].role === 'user') {
const userMessage = updatedMessages[userMessageIndex];
// Extract the actual text content without image/file markdown
const content = userMessage.content;
// Remove markdown image/file prefix if present
const markdownMatch = content.match(/^(?:\!\[.*?\]\(.*?\)|\[.*?\]\(.*?\))\n(.*)$/s);
const textToRestore = markdownMatch ? markdownMatch[1] : content;
// Restore the user's text in the input field
setInputText(textToRestore);
}
updatedMessages.pop(); // Remove user message
setMessages(updatedMessages);
saveMessages(updatedMessages);
setBusy(false);
return;
}
setServerReply(data);
} catch (err) {
console.error("An error happened in the handling of the chatbot response.", {
err
});
setBusy(false);
setError(err.message || 'An error occurred while processing your request. Please try again.');
// Remove the "thinking" message that was added
setMessages(prevMessages => {
const lastMessage = prevMessages[prevMessages.length - 1];
if (lastMessage && lastMessage.role === 'assistant' && lastMessage.content === '') {
return prevMessages.slice(0, -1);
}
return prevMessages;
});
}
}, [busy, uploadedFile, messages, saveMessages, stream, botId, customId, sessionId, chatId, contextId, atts, inputText, debugMode, restNonce, refreshRestNonce, restUrl]);
const onSubmitAction = useCallback((forcedText = null) => {
var _chatbotInputRef$curr2;
const hasFileUploaded = !!(uploadedFile !== null && uploadedFile !== void 0 && uploadedFile.uploadedId);
hasFocusRef.current = ((_chatbotInputRef$curr2 = chatbotInputRef.current) === null || _chatbotInputRef$curr2 === void 0 ? void 0 : _chatbotInputRef$curr2.currentElement) && document.activeElement === chatbotInputRef.current.currentElement();
if (forcedText) {
onSubmit(forcedText);
} else if (hasFileUploaded || inputText.length > 0) {
onSubmit(inputText);
}
}, [inputText, onSubmit, uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.uploadedId]);
// This is called when the user uploads an image or file.
const onFileUpload = async (file, type = "N/A", purpose = "N/A") => {
try {
if (file === null) {
resetUploadedFile();
return;
}
const params = {
type,
purpose
};
const url = `${restUrl}/mwai-ui/v1/files/upload`;
// Upload with progress
const nonce = restNonceRef.current ?? (await refreshRestNonce());
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_2__.mwaiFetchUpload)(url, file, nonce, progress => {
setUploadedFile({
localFile: file,
uploadedId: null,
uploadedUrl: null,
uploadProgress: progress
});
}, params);
setUploadedFile({
localFile: file,
uploadedId: res.data.id,
uploadedUrl: res.data.url,
uploadProgress: null
});
} catch (error) {
console.error('onFileUpload Error', error);
setError(error.message || 'An unknown error occurred');
resetUploadedFile();
}
};
// This is called when the user uploads an image or file.
// TODO: Why don't we have the resetError in onFileUpload and remove this function?
const onUploadFile = async file => {
if (error) {
resetError();
}
return onFileUpload(file);
};
const resetUploadedFile = () => {
setUploadedFile({
localFile: null,
uploadedId: null,
uploadedUrl: null,
uploadProgress: null
});
};
// #endregion
// #region Timer
const runTimer = useCallback(() => {
const timer = setTimeout(() => {
setOpen(prevOpen => {
if (!prevOpen) {
setShowIconMessage(true);
}
return prevOpen;
});
}, iconTextDelay * 1000);
return () => clearTimeout(timer);
}, [iconText, iconTextDelay]);
useEffect(() => {
if (iconText && !iconTextDelay) {
setShowIconMessage(true);
} else if (iconText && iconTextDelay) {
return runTimer();
}
}, [iconText]);
// #endregion
// #region Tasks Queue
const [tasks, setTasks] = useState([]);
const runTasks = useCallback(async () => {
if (tasks.length > 0) {
const task = tasks[0];
if (task.action === 'ask') {
const {
text,
submit
} = task.data;
if (submit) {
onSubmit(text);
} else {
setInputText(text);
}
} else if (task.action === 'toggle') {
setOpen(prevOpen => !prevOpen);
} else if (task.action === 'open') {
setOpen(true);
} else if (task.action === 'close') {
setOpen(false);
} else if (task.action === 'clear') {
const {
chatId
} = task.data;
onClear({
chatId
});
} else if (task.action === 'setContext') {
const {
chatId,
messages,
previousResponseId
} = task.data;
setChatId(chatId);
setMessages(messages);
if (previousResponseId) {
setPreviousResponseId(previousResponseId);
}
// Mark as resuming conversation when loading from Discussions Module
setIsResumingConversation(true);
setIsConversationLoaded(true);
// Clear shortcuts when loading an existing discussion
setShortcuts([]);
// Save to localStorage to persist the loaded conversation
saveMessages(messages);
} else if (task.action === 'setShortcuts') {
const shortcuts = task.data;
handleShortcuts(shortcuts);
} else if (task.action === 'setBlocks') {
const blocks = task.data;
handleBlocks(blocks);
} else if (task.action === 'addBlock') {
const block = task.data;
setBlocks(prevBlocks => {
return [...prevBlocks, block];
});
} else if (task.action === 'removeBlockById') {
const blockId = task.data;
setBlocks(prevBlocks => {
return prevBlocks.filter(block => block.id !== blockId);
});
}
setTasks(prevTasks => prevTasks.slice(1));
}
}, [tasks, onClear, onSubmit, setChatId, setInputText, setMessages, setOpen, handleShortcuts, handleBlocks]);
useEffect(() => {
runTasks();
}, [runTasks]);
// #endregion
const actions = {
// Text Chatbot
setInputText,
saveMessages,
setMessages,
resetMessages,
setError,
resetError,
onClear,
onSubmit,
onSubmitAction,
onFileUpload,
onUploadFile,
setOpen,
setWindowed,
setShowIconMessage,
setIsListening,
setDraggingType,
setIsBlocked,
// Realtime Chatbot
onStartRealtimeSession,
onRealtimeFunctionCallback,
onCommitStats,
onCommitDiscussions
};
const state = {
theme,
botId,
customId,
userData,
pluginUrl,
inputText,
messages,
shortcuts,
// Quick actions are buttons that can be displayed in the chat.
blocks,
// Blocks are used to display HTML content. A form, a video, etc.
busy,
error,
setBusy,
typewriter,
speechRecognition,
speechSynthesis,
virtualKeyboardFix,
localMemory,
isRealtime,
imageUpload,
fileUpload,
uploadedFile,
fileSearch,
textSend,
textClear,
textInputMaxLength,
textInputPlaceholder,
textCompliance,
aiName,
userName,
guestName,
aiAvatar,
userAvatar,
guestAvatar,
aiAvatarUrl,
userAvatarUrl,
guestAvatarUrl,
isWindow,
copyButton,
headerSubtitle,
fullscreen,
icon,
iconText,
iconAlt,
iconPosition,
iconBubble,
cssVariables,
iconUrl,
chatbotInputRef,
conversationRef,
isMobile,
open,
locked,
windowed,
showIconMessage,
timeElapsed,
isListening,
speechRecognitionAvailable,
uploadIconPosition,
submitButtonConf,
draggingType,
isBlocked,
busyNonce,
debugMode,
eventLogs,
system // Add the full system object
};
return /*#__PURE__*/React.createElement(ChatbotContext.Provider, {
value: {
state,
actions
}
}, children);
};
/***/ }),
/***/ "./app/js/chatbot/ChatbotEvents.js":
/*!*****************************************!*\
!*** ./app/js/chatbot/ChatbotEvents.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/wrench.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/activity.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/brain.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/search.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/circle-alert.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/x.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/minimize-2.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/maximize-2.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/chevron-down.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/chevron-right.js");
/* harmony import */ var markdown_to_jsx__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! markdown-to-jsx */ "./node_modules/markdown-to-jsx/dist/index.modern.js");
const {
useState,
useMemo,
useEffect
} = wp.element;
const ChatbotEvents = ({
allStreamData,
debugMode,
onClear,
hasData,
isWindow
}) => {
const [expanded, setExpanded] = useState({});
const [isVisible, setIsVisible] = useState(false); // Default to hidden/minimized
const [showAll, setShowAll] = useState(isWindow ? false : true); // Minimal view (false) in popup mode, full view otherwise
// Process all stream data into chunks
const chunks = useMemo(() => {
if (!allStreamData || allStreamData.length === 0) {
return [];
}
const processedData = allStreamData.map((data, index) => ({
...data,
id: `${data.messageId}-${index}`,
displayTime: new Date(data.timestamp).toLocaleTimeString('en-US', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})
})).reverse(); // Newest first
// If showAll is false, only show the last event
if (!showAll) {
return processedData.slice(0, 1);
}
// Otherwise show up to 20 events
return processedData.slice(0, 20);
}, [allStreamData, showAll]);
// Map subtypes to simplified categories
const getEventCategory = (subtype, metadata) => {
switch (subtype) {
case 'tool_call':
case 'tool_args':
return 'function';
case 'tool_result':
// Check if this is an MCP result by looking at the metadata
if ((metadata === null || metadata === void 0 ? void 0 : metadata.is_mcp) === true) {
return 'mcp';
}
// Legacy check: look for previous mcp_tool_call event
if (metadata !== null && metadata !== void 0 && metadata.tool_name && chunks.some(c => {
var _c$metadata;
return c.subtype === 'mcp_tool_call' && ((_c$metadata = c.metadata) === null || _c$metadata === void 0 ? void 0 : _c$metadata.name) === metadata.tool_name;
})) {
return 'mcp';
}
return 'function';
case 'mcp_discovery':
case 'mcp_tool_call':
case 'mcp_tool_result':
return 'mcp';
case 'thinking':
return 'thinking';
case 'status':
return 'output';
// Most status events are about output
case 'web_search':
case 'file_search':
return 'search';
case 'error':
return 'error';
case 'warning':
return 'warning';
case 'content':
return 'output';
default:
return subtype;
}
};
const getIcon = category => {
switch (category) {
case 'function':
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_0__["default"], {
size: 14
});
case 'mcp':
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_1__["default"], {
size: 14
});
case 'thinking':
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_2__["default"], {
size: 14
});
case 'output':
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_1__["default"], {
size: 14
});
case 'search':
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_3__["default"], {
size: 14
});
case 'error':
case 'warning':
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_4__["default"], {
size: 14
});
default:
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_1__["default"], {
size: 14
});
}
};
const getCategoryColor = (category, data) => {
switch (category) {
case 'function':
return '#3b82f6';
// blue for function calls
case 'mcp':
return '#8b5cf6';
// purple for MCP discovery
case 'thinking':
return '#8b5cf6';
// purple
case 'output':
// Different colors for different output messages
if (data && data.includes('completed')) {
return '#10b981'; // green for completion
}
if (data && data.includes('started') || data && data.includes('...')) {
return '#06b6d4'; // cyan for in-progress
}
return '#6b7280';
// gray for other output
case 'search':
return '#f59e0b';
// amber
case 'error':
return '#ef4444';
// red
case 'warning':
return '#f97316';
// orange
default:
return '#6b7280';
// gray
}
};
const toggleExpanded = chunkId => {
setExpanded(prev => ({
...prev,
[chunkId]: !prev[chunkId]
}));
};
// Get the latest meaningful event for status display
const latestEvent = useMemo(() => {
if (chunks.length === 0) return null;
// Look for the most recent meaningful status
for (const chunk of chunks) {
const category = getEventCategory(chunk.subtype, chunk.metadata);
// Show all events except debug and heartbeat
if (chunk.subtype !== 'debug' && chunk.subtype !== 'heartbeat') {
// For completed events, check if it's the stream completed message
if (chunk.data.includes('Stream completed')) {
// Find if there's a request completed message after this
const completedIndex = chunks.findIndex(c => c.data.includes('Request completed'));
if (completedIndex >= 0 && completedIndex < chunks.indexOf(chunk)) {
// Use the request completed message instead
const completedChunk = chunks[completedIndex];
return {
data: completedChunk.data,
category: getEventCategory(completedChunk.subtype, completedChunk.metadata),
color: getCategoryColor(getEventCategory(completedChunk.subtype, completedChunk.metadata), completedChunk.data)
};
}
}
return {
data: chunk.data,
category: category,
color: getCategoryColor(category, chunk.data)
};
}
}
return null;
}, [chunks]);
return /*#__PURE__*/React.createElement("div", {
className: `mwai-chunks ${!isVisible ? 'mwai-chunks-collapsed' : ''}`
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-chunks-header"
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_1__["default"], {
size: 12
}), /*#__PURE__*/React.createElement("span", {
className: "mwai-chunks-title"
}, "Events", latestEvent && /*#__PURE__*/React.createElement("span", {
className: "mwai-chunks-status",
style: {
color: latestEvent.color
}
}, ": ", latestEvent.data)), isVisible && /*#__PURE__*/React.createElement(React.Fragment, null, chunks.length > 0 && onClear && /*#__PURE__*/React.createElement("div", {
className: "mwai-chunks-toggle",
onClick: onClear,
title: "Clear stream events"
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_5__["default"], {
size: 12
})), !isWindow && /*#__PURE__*/React.createElement("div", {
className: "mwai-chunks-toggle",
onClick: () => setShowAll(!showAll),
title: showAll ? "Show minimal (last event only)" : "Show detailed (all events)"
}, showAll ? /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_6__["default"], {
size: 12
}) : /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_7__["default"], {
size: 12
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-chunks-toggle",
onClick: () => setIsVisible(!isVisible),
title: isVisible ? "Hide events" : "Show events"
}, isVisible ? /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_8__["default"], {
size: 12
}) : /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_9__["default"], {
size: 12
}))), isVisible && (chunks.length === 0 ? /*#__PURE__*/React.createElement("div", {
className: "mwai-chunk"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-chunk-header"
}, /*#__PURE__*/React.createElement("span", {
className: "mwai-chunk-time"
}, "--:--:--"), /*#__PURE__*/React.createElement("span", {
className: "mwai-chunk-type",
style: {
backgroundColor: '#6b7280'
}
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_1__["default"], {
size: 14
}), "waiting"), /*#__PURE__*/React.createElement("span", {
className: "mwai-chunk-data"
}, "No events yet."))) : chunks.map(chunk => {
const isExpanded = expanded[chunk.id];
const category = getEventCategory(chunk.subtype, chunk.metadata);
const hasDetails = chunk.metadata && Object.keys(chunk.metadata).length > 0 || category === 'thinking';
return /*#__PURE__*/React.createElement("div", {
key: chunk.id,
className: "mwai-chunk"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-chunk-header",
onClick: () => hasDetails && toggleExpanded(chunk.id)
}, /*#__PURE__*/React.createElement("span", {
className: "mwai-chunk-time"
}, chunk.displayTime), /*#__PURE__*/React.createElement("span", {
className: "mwai-chunk-type",
style: {
backgroundColor: getCategoryColor(category, chunk.data)
}
}, getIcon(category), category), /*#__PURE__*/React.createElement("span", {
className: "mwai-chunk-data"
}, (() => {
const dataStr = typeof chunk.data === 'string' ? chunk.data : JSON.stringify(chunk.data);
if (category === 'thinking') {
// Check if the content starts with **something**
const headerMatch = dataStr.match(/^\*\*([^*]+)\*\*/);
if (headerMatch) {
// Show only the header text (no formatting)
return headerMatch[1];
}
// If no header found, show the beginning of the content
return dataStr.substring(0, 50) + (dataStr.length > 50 ? '...' : '');
}
return dataStr;
})()), hasDetails && /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_9__["default"], {
size: 12,
className: "mwai-chunk-expand",
style: {
transform: isExpanded ? 'rotate(90deg)' : 'none'
}
})), isExpanded && hasDetails && /*#__PURE__*/React.createElement("div", {
className: "mwai-chunk-details"
}, category === 'thinking' ? /*#__PURE__*/React.createElement("div", {
style: {
padding: '0px 10px',
fontFamily: 'system-ui'
}
}, (() => {
const dataStr = typeof chunk.data === 'string' ? chunk.data : JSON.stringify(chunk.data);
try {
return (0,markdown_to_jsx__WEBPACK_IMPORTED_MODULE_10__.compiler)(dataStr);
} catch (e) {
return /*#__PURE__*/React.createElement("pre", null, dataStr);
}
})()) : /*#__PURE__*/React.createElement("pre", null, JSON.stringify(chunk.metadata, null, 2))));
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotEvents);
/***/ }),
/***/ "./app/js/chatbot/ChatbotHeader.js":
/*!*****************************************!*\
!*** ./app/js/chatbot/ChatbotHeader.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/helpers */ "./app/js/helpers.js");
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers */ "./app/js/chatbot/helpers.js");
// React & Vendor Libs
const {
useMemo
} = wp.element;
function formatAvatar(aiName, pluginUrl, iconUrl, aiAvatarUrl) {
const getAvatarSrc = url => {
if ((0,_helpers__WEBPACK_IMPORTED_MODULE_0__.isURL)(url)) {
return url;
} else if (url) {
return `${pluginUrl}/images/${url}`;
}
return null;
};
const renderAvatar = (src, alt) => /*#__PURE__*/React.createElement("div", {
className: "mwai-avatar"
}, /*#__PURE__*/React.createElement("img", {
alt: alt,
src: src
}));
const renderEmoji = emoji => /*#__PURE__*/React.createElement("div", {
className: "mwai-avatar mwai-emoji",
style: {
fontSize: '48px',
lineHeight: '48px'
}
}, emoji);
if ((0,_app_helpers__WEBPACK_IMPORTED_MODULE_1__.isEmoji)(aiAvatarUrl || iconUrl)) {
return renderEmoji(aiAvatarUrl || iconUrl);
}
// Priority: aiAvatarUrl > iconUrl > default image
const avatarSrc = getAvatarSrc(aiAvatarUrl) || iconUrl || `${pluginUrl}/images/chat-openai.svg`;
if (avatarSrc) {
return renderAvatar(avatarSrc, "AI Engine");
}
// If no avatar is available, return the aiName as text
return /*#__PURE__*/React.createElement("div", {
className: "mwai-name-text"
}, aiName);
}
const ChatbotHeader = () => {
const {
state,
actions
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_2__.useChatbotContext)();
const {
theme,
isWindow,
fullscreen,
aiName,
pluginUrl,
open,
iconUrl,
aiAvatarUrl,
windowed,
headerSubtitle
} = state;
const {
setOpen,
setWindowed
} = actions;
const headerContent = useMemo(() => {
if (!isWindow) {
return null;
}
const timelessStyle = (theme === null || theme === void 0 ? void 0 : theme.themeId) === 'timeless';
const avatarImage = timelessStyle ? formatAvatar(aiName, pluginUrl, iconUrl, aiAvatarUrl) : null;
const finalHeaderSubtitle = headerSubtitle === null || headerSubtitle === undefined ? "Discuss with" : headerSubtitle;
return /*#__PURE__*/React.createElement(React.Fragment, null, timelessStyle && /*#__PURE__*/React.createElement(React.Fragment, null, avatarImage, /*#__PURE__*/React.createElement("div", {
className: "mwai-name"
}, finalHeaderSubtitle && /*#__PURE__*/React.createElement("small", {
className: "mwai-subtitle"
}, finalHeaderSubtitle), /*#__PURE__*/React.createElement("div", null, aiName)), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-buttons"
}, fullscreen && /*#__PURE__*/React.createElement("div", {
className: "mwai-resize-button",
onClick: () => setWindowed(!windowed)
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-close-button",
onClick: () => setOpen(!open)
})));
}, [isWindow, theme === null || theme === void 0 ? void 0 : theme.themeId, aiName, pluginUrl, iconUrl, aiAvatarUrl, fullscreen, setWindowed, windowed, setOpen, open, headerSubtitle]);
return /*#__PURE__*/React.createElement("div", {
className: "mwai-header"
}, headerContent);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotHeader);
/***/ }),
/***/ "./app/js/chatbot/ChatbotInput.js":
/*!****************************************!*\
!*** ./app/js/chatbot/ChatbotInput.js ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var react_textarea_autosize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-textarea-autosize */ "./node_modules/react-textarea-autosize/dist/react-textarea-autosize.browser.development.esm.js");
/* harmony import */ var _app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _ChatUploadIcon__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChatUploadIcon */ "./app/js/chatbot/ChatUploadIcon.js");
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
// React & Vendor Libs
const {
useRef,
useState,
useEffect,
useImperativeHandle
} = wp.element;
const ChatbotInput = () => {
const css = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.useClasses)();
const {
state,
actions
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_1__.useChatbotContext)();
const {
inputText,
textInputMaxLength,
textInputPlaceholder,
error,
speechRecognitionAvailable,
isMobile,
conversationRef,
open,
uploadIconPosition,
locked,
isListening,
busy,
speechRecognition,
chatbotInputRef
} = state;
const {
onSubmitAction,
setIsListening,
resetError,
setInputText
} = actions;
const [composing, setComposing] = useState(false);
const inputRef = useRef();
useImperativeHandle(chatbotInputRef, () => ({
focusInput: () => {
var _inputRef$current;
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
},
currentElement: () => inputRef.current
}));
// Focus input when opening (except mobile)
useEffect(() => {
if (!isMobile && open) {
inputRef.current.focus();
}
if (conversationRef.current) {
conversationRef.current.scrollTop = conversationRef.current.scrollHeight;
}
}, [open, isMobile, conversationRef]);
const onTypeText = text => {
if (isListening) {
setIsListening(false);
}
if (error) {
resetError();
}
setInputText(text);
};
const classNames = css('mwai-input-text', {});
return /*#__PURE__*/React.createElement("div", {
ref: chatbotInputRef,
className: classNames
}, uploadIconPosition === 'mwai-input' && /*#__PURE__*/React.createElement(_ChatUploadIcon__WEBPACK_IMPORTED_MODULE_2__["default"], null), /*#__PURE__*/React.createElement(react_textarea_autosize__WEBPACK_IMPORTED_MODULE_3__["default"], {
ref: inputRef,
disabled: busy || locked,
placeholder: textInputPlaceholder,
value: inputText,
maxLength: textInputMaxLength,
onCompositionStart: () => setComposing(true),
onCompositionEnd: () => setComposing(false),
onKeyDown: event => {
if (composing) return;
if (event.code === 'Enter' && !event.shiftKey) {
event.preventDefault();
onSubmitAction();
}
},
onChange: e => onTypeText(e.target.value)
}), speechRecognition && /*#__PURE__*/React.createElement(_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.Microphone, {
active: isListening,
disabled: !speechRecognitionAvailable || busy,
className: "mwai-microphone",
onClick: () => setIsListening(!isListening)
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotInput);
/***/ }),
/***/ "./app/js/chatbot/ChatbotName.js":
/*!***************************************!*\
!*** ./app/js/chatbot/ChatbotName.js ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../helpers */ "./app/js/helpers.js");
// React & Vendor Libs
const {
useMemo
} = wp.element;
const ChatbotName = ({
role = 'user'
}) => {
const {
state
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.useChatbotContext)();
const {
pluginUrl,
iconUrl,
userData,
userName,
aiName,
guestName,
userAvatar,
aiAvatar,
guestAvatar,
userAvatarUrl,
aiAvatarUrl,
guestAvatarUrl
} = state;
const formattedOutput = useMemo(() => {
const isAi = role === 'assistant';
const isGuest = !userData && !isAi;
const getAvatarSrc = (url, isUserData = false) => {
if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isURL)(url)) {
return url;
} else if (url && !(0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isEmoji)(url)) {
return isUserData ? url : `${pluginUrl}/images/${url}`;
}
if (!isUserData && !(0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isEmoji)(url)) {
console.warn('Invalid URL for avatar:', url);
}
return null;
};
const renderAvatar = (src, alt) => /*#__PURE__*/React.createElement("div", {
className: "mwai-avatar"
}, /*#__PURE__*/React.createElement("img", {
width: "32",
height: "32",
src: src,
alt: alt
}));
const renderEmoji = emoji => /*#__PURE__*/React.createElement("div", {
className: "mwai-avatar mwai-emoji",
style: {
fontSize: '32px',
lineHeight: '32px'
}
}, emoji);
const renderName = name => /*#__PURE__*/React.createElement("div", {
className: "mwai-name-text"
}, name);
const getAvatarContent = (avatarEnabled, avatarUrl, fallbackUrl, altText, isUserData = false) => {
if (!avatarEnabled) return null;
if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isEmoji)(avatarUrl)) {
return renderEmoji(avatarUrl);
}
const src = getAvatarSrc(avatarUrl, isUserData) || fallbackUrl;
if (!src) return null;
return renderAvatar(src, altText);
};
if (isAi) {
const aiAvatarContent = getAvatarContent(aiAvatar, aiAvatarUrl, iconUrl, "AI Avatar");
if (aiAvatarContent) {
if (aiAvatarUrl === null && iconUrl) {
console.warn('Using iconUrl as a temporary fallback for AI avatar. Please set aiAvatarUrl.');
}
return aiAvatarContent;
}
return renderName(aiName);
}
if (!isGuest) {
const userAvatarContent = getAvatarContent(userAvatar, userAvatarUrl, userData === null || userData === void 0 ? void 0 : userData.AVATAR_URL, "User Avatar", true);
if (userAvatarContent) return userAvatarContent;
return renderName(formatName(userName, guestName, userData));
}
if (isGuest) {
const guestAvatarContent = getAvatarContent(guestAvatar, guestAvatarUrl, null, "Guest Avatar");
if (guestAvatarContent) return guestAvatarContent;
return renderName(guestName || "Guest");
}
}, [role, aiName, userName, guestName, userData, iconUrl, aiAvatar, userAvatar, guestAvatar, aiAvatarUrl, userAvatarUrl, guestAvatarUrl, pluginUrl]);
return /*#__PURE__*/React.createElement("span", {
className: "mwai-name"
}, formattedOutput);
};
function formatName(template, guestName, userData) {
if (!userData || Object.keys(userData).length === 0) {
return guestName || template || "Guest";
}
return Object.entries(userData).reduce((acc, [placeholder, value]) => {
const realPlaceholder = `{${placeholder}}`;
return acc.includes(realPlaceholder) ? acc.replace(realPlaceholder, value) : acc;
}, template);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotName);
/***/ }),
/***/ "./app/js/chatbot/ChatbotRealtime.js":
/*!*******************************************!*\
!*** ./app/js/chatbot/ChatbotRealtime.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/play.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/loader.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/square.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/pause.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/users.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/captions.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/bug.js");
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _AudioVisualizer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./AudioVisualizer */ "./app/js/chatbot/AudioVisualizer.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../helpers */ "./app/js/helpers.js");
/* harmony import */ var _helpers_RealtimeEventEmitter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../helpers/RealtimeEventEmitter */ "./app/js/helpers/RealtimeEventEmitter.js");
/* harmony import */ var _constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants/streamTypes */ "./app/js/constants/streamTypes.js");
// React & Vendor Libs
const {
useState,
useRef,
useCallback,
useMemo,
useEffect
} = wp.element;
// Debug levels
const DEBUG_LEVELS = {
none: 0,
low: 1,
normal: 2,
high: 3,
verbose: 4
};
const CURRENT_DEBUG = DEBUG_LEVELS.low;
/** Only logs if CURRENT_DEBUG >= level. */
function debugLog(level, ...args) {
if (CURRENT_DEBUG >= level) console.log(...args);
}
/** Simplified parseUsage to gather 6 fields. */
function parseUsage(usage) {
if (!usage) return null;
const {
input_token_details: {
text_tokens: textIn = 0,
audio_tokens: audioIn = 0,
cached_tokens_details: {
text_tokens: cachedText = 0,
audio_tokens: cachedAudio = 0
} = {}
} = {},
output_token_details: {
text_tokens: textOut = 0,
audio_tokens: audioOut = 0
} = {}
} = usage;
return {
text_input_tokens: textIn,
audio_input_tokens: audioIn,
text_output_tokens: textOut,
audio_output_tokens: audioOut,
text_cached_tokens: cachedText,
audio_cached_tokens: cachedAudio
};
}
/**
* Representation of a chatbot participant (user or assistant).
*/
function getChatbotRepresentation(state, role = 'user') {
const {
pluginUrl,
iconUrl,
userData,
userName,
aiName,
guestName,
userAvatar,
aiAvatar,
guestAvatar,
userAvatarUrl,
aiAvatarUrl,
guestAvatarUrl
} = state;
const getAvatarSrc = (url, isUserData = false) => {
if ((0,_helpers__WEBPACK_IMPORTED_MODULE_0__.isURL)(url)) return url;
if (url && !(0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isEmoji)(url)) return isUserData ? url : `${pluginUrl}/images/${url}`;
return null;
};
const getRepresentation = (name, avatarEnabled, avatarUrl, fallbackUrl, isUserData = false) => {
if (avatarEnabled) {
const src = getAvatarSrc(avatarUrl, isUserData) || fallbackUrl;
if (src) return {
emoji: null,
text: null,
image: src,
use: 'image'
};
}
if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isEmoji)(name)) return {
emoji: name,
text: null,
image: null,
use: 'emoji'
};
return {
emoji: null,
text: name,
image: null,
use: 'text'
};
};
if (role === 'assistant') {
return getRepresentation(aiName, aiAvatar, aiAvatarUrl, iconUrl);
}
if (userData) {
const name = formatName(userName, guestName, userData);
return getRepresentation(name, userAvatar, userAvatarUrl, userData === null || userData === void 0 ? void 0 : userData.AVATAR_URL, true);
}
if (!userData && role === 'user') {
return getRepresentation(guestName || 'Guest', guestAvatar, guestAvatarUrl, null);
}
return {
emoji: null,
text: 'Unknown',
image: null,
use: 'text'
};
}
function formatName(template, guestName, userData) {
if (!userData || Object.keys(userData).length === 0) return guestName || template || 'Guest';
return Object.entries(userData).reduce((acc, [key, val]) => {
const placeholder = `{${key}}`;
return acc.includes(placeholder) ? acc.replace(placeholder, val) : acc;
}, template);
}
const ChatbotRealtime = ({
onMessagesUpdate,
onStreamEvent
}) => {
const {
state,
actions
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_2__.useChatbotContext)();
const {
busy,
locked,
open,
popup,
system
} = state;
const {
onStartRealtimeSession,
onRealtimeFunctionCallback,
onCommitStats,
onCommitDiscussions,
setError
} = actions;
const debugMode = (system === null || system === void 0 ? void 0 : system.debugMode) || false;
const eventLogs = (system === null || system === void 0 ? void 0 : system.eventLogs) || false;
// Realtime session states
const [isConnecting, setIsConnecting] = useState(false);
const [isSessionActive, setIsSessionActive] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [sessionId, setSessionId] = useState(null);
const [whoIsSpeaking, setWhoIsSpeaking] = useState(null);
// Statistics
const [statistics, setStatistics] = useState({
text_input_tokens: 0,
audio_input_tokens: 0,
text_output_tokens: 0,
audio_output_tokens: 0,
text_cached_tokens: 0,
audio_cached_tokens: 0
});
// Conversation messages
const [messages, setMessages] = useState([]);
const processedItemIdsRef = useRef(new Set());
// Event callback for stream events - send directly to parent
const handleStreamEvent = useCallback((content, eventData) => {
if (eventData && eventData.subtype && onStreamEvent) {
// Send event directly to parent component
onStreamEvent({
...eventData,
timestamp: eventData.timestamp || new Date().getTime(),
messageId: 'realtime-session'
});
}
}, [onStreamEvent]);
// Initialize event emitter
const eventEmitterRef = useRef(null);
useEffect(() => {
eventEmitterRef.current = new _helpers_RealtimeEventEmitter__WEBPACK_IMPORTED_MODULE_3__["default"](handleStreamEvent, eventLogs);
}, [handleStreamEvent, eventLogs]);
// WebRTC references
const pcRef = useRef(null);
const dataChannelRef = useRef(null);
const localStreamRef = useRef(null);
const stopRealtimeConnectionRef = useRef(null);
// Toggles
const [showOptions, setShowOptions] = useState(true);
const [showUsers, setShowUsers] = useState(true);
const [showCaptions, setShowCaptions] = useState(false);
const [showStatistics, setShowStatistics] = useState(false);
// Assistant stream
const [assistantStream, setAssistantStream] = useState(null);
// Function callbacks from the server
const functionCallbacksRef = useRef([]);
// UI representation
const userUI = useMemo(() => getChatbotRepresentation(state, 'user'), [state]);
const assistantUI = useMemo(() => getChatbotRepresentation(state, 'assistant'), [state]);
// Cleanup
useEffect(() => {
if (!open && isSessionActive && popup) stopRealtimeConnection();
}, [open, popup, isSessionActive]);
// Update parent component with messages
useEffect(() => {
if (onMessagesUpdate) {
onMessagesUpdate(messages);
}
}, [messages, onMessagesUpdate]);
/**
* Helper: Send updated stats to your WordPress REST API.
*/
const commitStatsToServer = useCallback(async usageStats => {
// usageStats contains {text_input_tokens, audio_input_tokens, text_output_tokens, ...}
const result = await onCommitStats(usageStats);
// Check if user has exceeded limits
if (result.overLimit) {
// Emit an event about the limit being exceeded
if (eventLogs && eventEmitterRef.current) {
eventEmitterRef.current.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.ERROR, result.limitMessage || 'Usage limit exceeded', {
visibility: 'visible',
error: true
});
}
// Stop the realtime connection
console.warn('Usage limit exceeded, stopping realtime connection:', result.limitMessage);
if (stopRealtimeConnectionRef.current) {
stopRealtimeConnectionRef.current();
}
}
}, [onCommitStats, eventLogs]);
/**
* Enable audio transcription (Whisper).
*/
const enableAudioTranscription = useCallback(() => {
if (!dataChannelRef.current || dataChannelRef.current.readyState !== 'open') {
console.error('Data channel is not open yet; cannot enable transcription.');
return;
}
dataChannelRef.current.send(JSON.stringify({
type: 'session.update',
session: {
input_audio_transcription: {
model: 'whisper-1'
}
}
}));
debugLog(DEBUG_LEVELS.low, 'Sent session.update to enable Whisper.');
}, []);
/**
* Handle real-time function calls from the AI.
*/
const handleFunctionCall = useCallback(async (callId, functionName, rawArgs) => {
let parsedArgs = {};
try {
parsedArgs = JSON.parse(rawArgs || '{}');
} catch (err) {
console.error('Could not parse function arguments.', rawArgs);
}
const fns = functionCallbacksRef.current;
const cb = fns.find(f => f.name === functionName);
if (!cb) {
console.error(`No match for callback: '${functionName}'.`);
return;
}
try {
var _dataChannelRef$curre;
const result = await onRealtimeFunctionCallback(cb.id, cb.type, cb.name, cb.target, parsedArgs);
if (!(result !== null && result !== void 0 && result.success)) {
console.error('Callback failed.', result === null || result === void 0 ? void 0 : result.message);
// Function error will be shown in stream events
return;
}
const functionOutput = result.data;
// Emit function result event
if (eventLogs && eventEmitterRef.current) {
const resultPreview = typeof functionOutput === 'string' ? functionOutput : JSON.stringify(functionOutput);
const previewText = resultPreview.length > 100 ? resultPreview.substring(0, 100) + '...' : resultPreview;
eventEmitterRef.current.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.TOOL_RESULT, `Got result from ${functionName}.`, {
metadata: {
tool_name: functionName,
result: previewText,
call_id: callId
}
});
}
if (((_dataChannelRef$curre = dataChannelRef.current) === null || _dataChannelRef$curre === void 0 ? void 0 : _dataChannelRef$curre.readyState) === 'open') {
debugLog(DEBUG_LEVELS.low, 'Send callback value:', functionOutput);
dataChannelRef.current.send(JSON.stringify({
type: 'conversation.item.create',
item: {
type: 'function_call_output',
call_id: callId,
output: JSON.stringify(functionOutput)
}
}));
dataChannelRef.current.send(JSON.stringify({
type: 'response.create',
response: {
instructions: "Reply based on the function's output."
}
}));
}
} catch (err) {
console.error('Error in handleFunctionCall.', err);
}
}, [onRealtimeFunctionCallback, eventLogs]);
/**
* Start the Realtime connection.
*/
const startRealtimeConnection = useCallback(async (clientSecret, model) => {
setIsConnecting(true);
// Emit session starting event
if (eventLogs && eventEmitterRef.current) {
eventEmitterRef.current.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.STATUS, 'Starting realtime session...', {
visibility: 'visible'
});
}
const pc = new RTCPeerConnection();
pcRef.current = pc;
let ms;
try {
// Check if mediaDevices API is available
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
throw new Error('MediaDevices API not available. Please ensure you are using HTTPS and a modern browser.');
}
ms = await navigator.mediaDevices.getUserMedia({
audio: true
});
localStreamRef.current = ms;
ms.getTracks().forEach(track => pc.addTrack(track, ms));
} catch (err) {
console.error('Error accessing microphone.', err);
// Emit error event
if (eventLogs && eventEmitterRef.current) {
eventEmitterRef.current.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.STATUS, 'Failed to access microphone: ' + err.message, {
visibility: 'visible',
error: true
});
}
// Show error to user
setError('Failed to access microphone. Please ensure microphone permissions are granted and try again.');
setIsConnecting(false);
return;
}
pc.ontrack = event => {
const audioEl = document.getElementById('mwai-audio');
if (audioEl) audioEl.srcObject = event.streams[0];
setAssistantStream(event.streams[0]);
};
const dataChannel = pc.createDataChannel('oai-events');
dataChannelRef.current = dataChannel;
dataChannel.addEventListener('open', () => {
debugLog(DEBUG_LEVELS.low, 'Data channel open.');
// Emit session connected event
if (eventLogs && eventEmitterRef.current) {
eventEmitterRef.current.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.STATUS, 'Realtime session connected', {
visibility: 'visible'
});
}
enableAudioTranscription();
});
dataChannel.addEventListener('message', e => {
let msg;
try {
msg = JSON.parse(e.data);
} catch (err) {
console.error('Could not parse Realtime message.', e.data);
return;
}
if (CURRENT_DEBUG >= DEBUG_LEVELS.high) {
console.log('Incoming message from Realtime API.', msg);
} else if (CURRENT_DEBUG === DEBUG_LEVELS.low) {
var _msg$type;
const isMajor = ((_msg$type = msg.type) === null || _msg$type === void 0 ? void 0 : _msg$type.endsWith('.done')) || msg.type === 'input_audio_buffer.committed' || msg.type === 'conversation.item.input_audio_transcription.completed' || msg.type === 'response.done';
if (isMajor) console.log('Key event from Realtime API.', msg);
}
// Emit stream event for important realtime API events only
if (eventLogs && msg.type && eventEmitterRef.current) {
let eventMessage = '';
let eventSubtype = _constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.STATUS;
let shouldEmit = false;
// Only emit events for key moments
switch (msg.type) {
case 'input_audio_buffer.speech_started':
eventMessage = 'User started talking...';
shouldEmit = true;
break;
case 'input_audio_buffer.speech_stopped':
eventMessage = 'User stopped speaking.';
shouldEmit = true;
break;
case 'response.audio.started':
eventMessage = 'Assistant started speaking.';
shouldEmit = true;
break;
case 'response.audio.done':
eventMessage = 'Assistant stopped speaking.';
shouldEmit = true;
break;
case 'conversation.item.input_audio_transcription.completed':
eventMessage = 'Got transcript from user.';
eventSubtype = _constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.TRANSCRIPT;
shouldEmit = true;
break;
case 'response.audio_transcript.done':
eventMessage = 'Got transcript from assistant.';
eventSubtype = _constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.TRANSCRIPT;
shouldEmit = true;
break;
case 'response.function_call_arguments.done':
eventMessage = `Calling ${msg.name}...`;
eventSubtype = _constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.TOOL_CALL;
shouldEmit = true;
break;
case 'response.done':
// Don't emit this event - it's too verbose
break;
}
if (shouldEmit) {
eventEmitterRef.current.emit(eventSubtype, eventMessage, {
visibility: 'visible',
metadata: {
event_type: msg.type,
event_id: msg.event_id
}
});
}
}
switch (msg.type) {
case 'input_audio_buffer.committed':
{
const itemId = msg.item_id;
if (!processedItemIdsRef.current.has(itemId)) {
processedItemIdsRef.current.add(itemId);
setMessages(prev => [...prev, {
id: itemId,
role: 'user',
content: '[Audio]'
}]);
}
setWhoIsSpeaking('user');
break;
}
case 'conversation.item.input_audio_transcription.completed':
{
const itemId = msg.item_id;
const transcript = (msg.transcript || '[Audio]').trim();
setMessages(prev => prev.map(m => m.id === itemId && m.role === 'user' ? {
...m,
content: transcript
} : m));
break;
}
case 'response.audio_transcript.done':
{
const itemId = msg.item_id;
const transcript = (msg.transcript || '[Audio]').trim();
setWhoIsSpeaking('assistant');
if (!processedItemIdsRef.current.has(itemId)) {
processedItemIdsRef.current.add(itemId);
setMessages(prev => [...prev, {
id: itemId,
role: 'assistant',
content: transcript
}]);
}
break;
}
case 'response.function_call_arguments.done':
{
const {
call_id,
name,
arguments: rawArgs
} = msg;
debugLog(DEBUG_LEVELS.low, 'Function call requested.', call_id, name);
handleFunctionCall(call_id, name, rawArgs);
break;
}
case 'response.done':
{
const resp = msg.response;
if (resp !== null && resp !== void 0 && resp.usage) {
const usageStats = parseUsage(resp.usage);
if (usageStats) {
setStatistics(prev => {
const updated = {
text_input_tokens: (prev.text_input_tokens || 0) + usageStats.text_input_tokens,
audio_input_tokens: (prev.audio_input_tokens || 0) + usageStats.audio_input_tokens,
text_output_tokens: (prev.text_output_tokens || 0) + usageStats.text_output_tokens,
audio_output_tokens: (prev.audio_output_tokens || 0) + usageStats.audio_output_tokens,
text_cached_tokens: (prev.text_cached_tokens || 0) + usageStats.text_cached_tokens,
audio_cached_tokens: (prev.audio_cached_tokens || 0) + usageStats.audio_cached_tokens
};
commitStatsToServer(updated);
return updated;
});
}
}
setWhoIsSpeaking('user');
break;
}
default:
// ignore partial or unrecognized events
break;
}
});
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const baseUrl = 'https://api.openai.com/v1/realtime';
const chosenModel = model || 'gpt-4o-preview-2024-12-17';
const sdpResponse = await fetch(`${baseUrl}?model=${chosenModel}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${clientSecret}`,
'Content-Type': 'application/sdp'
},
body: offer.sdp
});
if (!sdpResponse.ok) {
console.error('SDP exchange failed.', sdpResponse);
setIsConnecting(false);
return;
}
const answerSDP = await sdpResponse.text();
await pc.setRemoteDescription({
type: 'answer',
sdp: answerSDP
});
debugLog(DEBUG_LEVELS.low, 'Realtime connection established.');
setIsConnecting(false);
setIsSessionActive(true);
setIsPaused(false);
setWhoIsSpeaking('user');
}, [enableAudioTranscription, handleFunctionCall, commitStatsToServer, setError]);
/**
* Stop the Realtime connection.
*/
const stopRealtimeConnection = useCallback(() => {
// Emit session ending event
if (eventLogs && eventEmitterRef.current) {
eventEmitterRef.current.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_4__.STREAM_TYPES.STATUS, 'Ending realtime session...', {
visibility: 'visible'
});
}
try {
if (pcRef.current) {
pcRef.current.close();
pcRef.current = null;
}
if (localStreamRef.current) {
localStreamRef.current.getTracks().forEach(track => track.stop());
localStreamRef.current = null;
}
dataChannelRef.current = null;
setIsConnecting(false);
setIsSessionActive(false);
setIsPaused(false);
setWhoIsSpeaking(null);
// Commit messages
onCommitDiscussions(messages);
// Reset states
setMessages([]);
setStatistics({
text_input_tokens: 0,
audio_input_tokens: 0,
text_output_tokens: 0,
audio_output_tokens: 0,
text_cached_tokens: 0,
audio_cached_tokens: 0
});
debugLog(DEBUG_LEVELS.low, 'Stopped Realtime connection.');
} catch (err) {
console.error('Error stopping connection.', err);
}
}, [messages, statistics, onCommitDiscussions]);
// Update the ref when the function changes
useEffect(() => {
stopRealtimeConnectionRef.current = stopRealtimeConnection;
}, [stopRealtimeConnection]);
/**
* Toggle microphone (pause/unpause).
*/
const togglePause = useCallback(() => {
if (!localStreamRef.current) return;
const tracks = localStreamRef.current.getAudioTracks();
if (!tracks.length) return;
if (isPaused) {
tracks.forEach(track => {
track.enabled = true;
});
debugLog(DEBUG_LEVELS.low, 'Resumed microphone.');
setIsPaused(false);
} else {
tracks.forEach(track => {
track.enabled = false;
});
debugLog(DEBUG_LEVELS.low, 'Paused microphone.');
setIsPaused(true);
}
}, [isPaused]);
/**
* Initiate the Realtime session on the server, then connect.
*/
const handlePlay = useCallback(async () => {
setIsConnecting(true);
try {
const data = await onStartRealtimeSession();
if (!(data !== null && data !== void 0 && data.success)) {
console.error('Could not start realtime session.', data);
setIsConnecting(false);
// Show error to user
const errorMessage = (data === null || data === void 0 ? void 0 : data.message) || 'Could not start realtime session.';
setError(errorMessage);
return;
}
functionCallbacksRef.current = data.function_callbacks || [];
setSessionId(data.session_id);
await startRealtimeConnection(data.client_secret, data.model);
} catch (err) {
console.error('Error in handlePlay.', err);
setIsConnecting(false);
// Show error to user
const errorMessage = err.message || 'An error occurred while starting the realtime session.';
setError(errorMessage);
}
}, [onStartRealtimeSession, startRealtimeConnection, setError]);
const handleStop = useCallback(() => stopRealtimeConnection(), [stopRealtimeConnection]);
// Toggles
const toggleUsers = useCallback(() => setShowUsers(p => !p), []);
const toggleStatistics = useCallback(() => setShowStatistics(p => !p), []);
const toggleCaptions = useCallback(() => setShowCaptions(p => !p), []);
// Class for Pause button
const pauseButtonClass = useMemo(() => isPaused ? 'mwai-pause mwai-active' : 'mwai-pause', [isPaused]);
const latestAssistantMessage = useMemo(() => {
const reversed = [...messages].reverse();
const last = reversed.find(m => m.role === 'assistant');
if (!last) return '...';
if (last.content.length > 256) return `${last.content.slice(0, 256)}...`;
return last.content;
}, [messages]);
const usersOptionClasses = useMemo(() => showUsers ? 'mwai-option mwai-option-users mwai-active' : 'mwai-option mwai-option-users', [showUsers]);
const captionsOptionClasses = useMemo(() => showCaptions ? 'mwai-option mwai-option-captions mwai-active' : 'mwai-option mwai-option-captions', [showCaptions]);
const statisticsOptionClasses = useMemo(() => showStatistics ? 'mwai-option mwai-option-statistics mwai-active' : 'mwai-option mwai-option-statistics', [showStatistics]);
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("audio", {
id: "mwai-audio",
autoPlay: true
}), showUsers && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'center'
}
}, /*#__PURE__*/React.createElement(_AudioVisualizer__WEBPACK_IMPORTED_MODULE_5__["default"], {
assistantStream: assistantStream,
userUI: userUI,
assistantUI: assistantUI,
userStream: localStreamRef.current
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-controls"
}, !isSessionActive && !isConnecting && /*#__PURE__*/React.createElement("button", {
onClick: handlePlay,
className: "mwai-play",
disabled: busy || locked,
"aria-label": "Play"
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_6__["default"], {
size: 16
})), isConnecting && /*#__PURE__*/React.createElement("button", {
className: "mwai-play",
disabled: true
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_7__["default"], {
size: 16,
style: {
animation: 'spin 0.8s linear infinite'
}
})), isSessionActive && !isConnecting && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
onClick: handleStop,
className: "mwai-stop",
disabled: busy || locked,
"aria-label": "Stop"
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_8__["default"], {
size: 16
})), /*#__PURE__*/React.createElement("button", {
onClick: togglePause,
className: pauseButtonClass,
disabled: busy || locked,
"aria-label": "Pause"
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_9__["default"], {
size: 16
})))), showCaptions && latestAssistantMessage && latestAssistantMessage.length > 0 && /*#__PURE__*/React.createElement("div", {
className: "mwai-last-transcript"
}, latestAssistantMessage), showStatistics && /*#__PURE__*/React.createElement("div", {
className: "mwai-statistics"
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Text In"), /*#__PURE__*/React.createElement("span", null, statistics.text_input_tokens)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Text Out"), /*#__PURE__*/React.createElement("span", null, statistics.text_output_tokens)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Text Cached"), /*#__PURE__*/React.createElement("span", null, statistics.text_cached_tokens)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Audio In"), /*#__PURE__*/React.createElement("span", null, statistics.audio_input_tokens)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Audio Out"), /*#__PURE__*/React.createElement("span", null, statistics.audio_output_tokens)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Audio Cached"), /*#__PURE__*/React.createElement("span", null, statistics.audio_cached_tokens))), showOptions && /*#__PURE__*/React.createElement("div", {
className: "mwai-options"
}, /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_10__["default"], {
size: 13,
title: "Show Users",
className: usersOptionClasses,
onClick: toggleUsers
}), /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_11__["default"], {
size: 18,
title: "Show Captions",
className: captionsOptionClasses,
onClick: toggleCaptions
}), /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_12__["default"], {
size: 14,
title: "Show Statistics",
className: statisticsOptionClasses,
onClick: toggleStatistics
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotRealtime);
/***/ }),
/***/ "./app/js/chatbot/ChatbotReply.js":
/*!****************************************!*\
!*** ./app/js/chatbot/ChatbotReply.js ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @app/chatbot/helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _app_chatbot_ChatbotSpinners__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/chatbot/ChatbotSpinners */ "./app/js/chatbot/ChatbotSpinners.js");
/* harmony import */ var _app_components_ReplyActions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/components/ReplyActions */ "./app/js/components/ReplyActions.js");
/* harmony import */ var _ChatbotName__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChatbotName */ "./app/js/chatbot/ChatbotName.js");
/* harmony import */ var _ChatbotContent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ChatbotContent */ "./app/js/chatbot/ChatbotContent.js");
// React & Vendor Libs
const {
useState,
useMemo,
useEffect,
useRef
} = wp.element;
// AI Engine
// AI Engine (Used by TypedMessage)
//import Typed from 'typed.js';
//import { useInterval } from '@app/chatbot/helpers';
//import { applyFilters } from '@app/chatbot/MwaiAPI';
// If isUser, we render the content as-is, otherwise we render it as markdown.
const RawMessage = ({
message,
onRendered = () => {}
}) => {
const {
state
} = (0,_app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.useChatbotContext)();
const {
copyButton,
debugMode
} = state;
const [isLongProcess] = useState(message.isQuerying || message.isStreaming);
const isQuerying = message.isQuerying;
const isStreaming = message.isStreaming;
useEffect(() => {
if (!isLongProcess) {
onRendered();
} else if (isLongProcess && !isQuerying && !isStreaming) {
onRendered();
}
}, [isLongProcess, isQuerying, isStreaming]);
// For non-streaming queries, show bouncing dots
if (isQuerying) {
return /*#__PURE__*/React.createElement(_app_chatbot_ChatbotSpinners__WEBPACK_IMPORTED_MODULE_1__.BouncingDots, null);
}
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_ChatbotName__WEBPACK_IMPORTED_MODULE_2__["default"], {
role: message.role
}), /*#__PURE__*/React.createElement(_app_components_ReplyActions__WEBPACK_IMPORTED_MODULE_3__["default"], {
content: message.content,
enabled: copyButton,
className: "mwai-text"
}, /*#__PURE__*/React.createElement(_ChatbotContent__WEBPACK_IMPORTED_MODULE_4__["default"], {
message: message
})));
};
const ImagesMessage = ({
message,
onRendered = () => {}
}) => {
const [images, setImages] = useState(message === null || message === void 0 ? void 0 : message.images);
useEffect(() => {
onRendered();
});
const handleImageError = index => {
const placeholderImage = "https://placehold.co/600x200?text=Expired+Image";
setImages(prevImages => prevImages.map((img, i) => i === index ? placeholderImage : img));
};
if (message.isQuerying) {
return /*#__PURE__*/React.createElement(_app_chatbot_ChatbotSpinners__WEBPACK_IMPORTED_MODULE_1__.BouncingDots, null);
}
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_ChatbotName__WEBPACK_IMPORTED_MODULE_2__["default"], {
role: message.role
}), /*#__PURE__*/React.createElement("span", {
className: "mwai-text"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-gallery"
}, images === null || images === void 0 ? void 0 : images.map((image, index) => /*#__PURE__*/React.createElement("a", {
key: index,
href: image,
target: "_blank",
rel: "noopener noreferrer"
}, /*#__PURE__*/React.createElement("img", {
key: index,
src: image,
onError: () => handleImageError(index)
}))))));
};
// const TypedMessage = ({ message, conversationRef, onRendered = () => {} }) => {
// const typedElement = useRef(null);
// const [ dynamic ] = useState(message.isQuerying);
// const [ ready, setReady ] = useState(!message.isQuerying);
// const content = message.content;
// useEffect(() => {
// console.warn("Do not use the Typewriter Effect. Use Streaming instead.");
// }, []);
// useInterval(200, () => {
// if (!conversationRef?.current) {
// return;
// }
// }, !ready);
// useEffect(() => {
// if (!dynamic) {
// onRendered();
// return;
// }
// if (!typedElement.current) {
// return;
// }
// const options = {
// strings: [content],
// typeSpeed: applyFilters('typewriter.speed', 15),
// showCursor: false,
// onComplete: (self) => {
// if (self.cursor) {
// self.cursor.remove();
// }
// onRendered();
// setReady(() => true);
// },
// };
// const typed = new Typed(typedElement.current, options);
// return () => { typed.destroy(); };
// }, [message, message.isQuerying]);
// const renderedContent = useMemo(() => {
// let out = "";
// try {
// out = compiler(content);
// }
// catch (e) {
// console.error("Crash in markdown-to-jsx! Reverting to plain text.", { e, content });
// out = content;
// }
// return out;
// }, [content]);
// return (
// <>
// {message.isQuerying && <BouncingDots />}
// {!message.isQuerying && dynamic && <>
// <ChatbotName role={message.role} />
// <span className="mwai-text" ref={typedElement} />
// </>}
// {!message.isQuerying && !dynamic && <>
// <ChatbotName role={message.role} />
// <span className="mwai-text">
// {renderedContent}
// </span>
// </>}
// </>
// );
// };
const ChatbotReply = ({
message,
conversationRef
}) => {
var _message$images;
const {
state
} = (0,_app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.useChatbotContext)();
const {
typewriter
} = state;
const css = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_5__.useClasses)();
const mainElement = useRef();
const classes = css('mwai-reply', {
'mwai-ai': message.role === 'assistant',
'mwai-user': message.role === 'user',
'mwai-system': message.role === 'system'
});
const isImages = (message === null || message === void 0 || (_message$images = message.images) === null || _message$images === void 0 ? void 0 : _message$images.length) > 0;
const onRendered = () => {
if (!mainElement.current) {
return;
}
if (message.isQuerying) {
return;
}
if (mainElement.current.classList.contains('mwai-rendered')) {
return;
}
if (typeof hljs !== 'undefined') {
mainElement.current.classList.add('mwai-rendered');
const selector = mainElement.current.querySelectorAll('pre code');
selector.forEach(el => {
// eslint-disable-next-line no-undef
hljs.highlightElement(el);
});
}
};
const output = useMemo(() => {
if (message.role === 'user') {
return /*#__PURE__*/React.createElement("div", {
ref: mainElement,
className: classes
}, /*#__PURE__*/React.createElement(RawMessage, {
message: message
}));
}
if (message.role === 'assistant') {
if (isImages) {
return /*#__PURE__*/React.createElement("div", {
ref: mainElement,
className: classes
}, /*#__PURE__*/React.createElement(ImagesMessage, {
message: message,
conversationRef: conversationRef,
onRendered: onRendered
}));
}
// else if (typewriter && !message.isStreaming) {
// console.warn("The Typewriter effect is deprecated. Use Streaming instead.");
// return <div ref={mainElement} className={classes}>
// <TypedMessage message={message} conversationRef={conversationRef} onRendered={onRendered} />
// </div>;
// }
return /*#__PURE__*/React.createElement("div", {
ref: mainElement,
className: classes
}, /*#__PURE__*/React.createElement(RawMessage, {
message: message,
conversationRef: conversationRef,
onRendered: onRendered
}));
}
if (message.role === 'system') {
return /*#__PURE__*/React.createElement("div", {
ref: mainElement,
className: classes
}, /*#__PURE__*/React.createElement(RawMessage, {
message: message,
conversationRef: conversationRef,
onRendered: onRendered
}));
}
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("i", null, "Unhandled role."));
}, [message, conversationRef, isImages, typewriter]);
return output;
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotReply);
/***/ }),
/***/ "./app/js/chatbot/ChatbotSpinners.js":
/*!*******************************************!*\
!*** ./app/js/chatbot/ChatbotSpinners.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ BouncingDots: () => (/* binding */ BouncingDots)
/* harmony export */ });
const BouncingDots = () => {
const bouncingLoaderStyles = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: 26
};
const bouncingDotStyles = {
width: 9,
height: 9,
margin: '5px 0px 0px 5px',
borderRadius: '50%',
backgroundColor: '#a3a1a1',
opacity: 1,
animation: 'bouncing-loader 0.4s infinite alternate'
};
const animationDelays = ['0.1s', '0.2s', '0.3s'];
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
@keyframes bouncing-loader {
to {
opacity: 0.6;
transform: translateY(-10px);
}
}
`), /*#__PURE__*/React.createElement("div", {
style: bouncingLoaderStyles
}, animationDelays.map((delay, index) => /*#__PURE__*/React.createElement("div", {
key: index,
style: {
...bouncingDotStyles,
animationDelay: delay
}
}))));
};
/***/ }),
/***/ "./app/js/chatbot/ChatbotSubmit.js":
/*!*****************************************!*\
!*** ./app/js/chatbot/ChatbotSubmit.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/send.js");
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/eraser.js");
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
// React & Vendor Libs
const {
useMemo,
useCallback
} = wp.element;
const ChatbotSubmit = () => {
const {
state,
actions
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.useChatbotContext)();
const {
onClear,
onSubmitAction,
setIsListening
} = actions;
const {
textClear,
textSend,
uploadedFile,
inputText,
messages,
isListening,
timeElapsed,
busy,
submitButtonConf,
locked
} = state;
const isFileUploading = !!(uploadedFile !== null && uploadedFile !== void 0 && uploadedFile.uploadProgress);
const hasFileUploaded = !!(uploadedFile !== null && uploadedFile !== void 0 && uploadedFile.uploadedId);
const clearMode = !hasFileUploaded && inputText.length < 1 && (messages === null || messages === void 0 ? void 0 : messages.length) > 1;
const buttonContent = useMemo(() => {
if (busy) {
return timeElapsed ? /*#__PURE__*/React.createElement("div", {
className: "mwai-timer"
}, timeElapsed) : null;
}
// If there are text values for the button, use them
if (submitButtonConf !== null && submitButtonConf !== void 0 && submitButtonConf.imageSend && submitButtonConf !== null && submitButtonConf !== void 0 && submitButtonConf.imageClear) {
return /*#__PURE__*/React.createElement("img", {
src: clearMode ? submitButtonConf.imageClear : submitButtonConf.imageSend,
alt: clearMode ? textClear : textSend
});
}
// If there are no text or images, use the default send icon
if (!clearMode && !textSend) {
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_1__["default"], {
size: "20",
style: {
marginLeft: 10
}
});
}
if (clearMode && !textClear) {
return /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_2__["default"], {
size: "20"
});
}
return /*#__PURE__*/React.createElement("span", null, clearMode ? textClear : textSend);
}, [busy, timeElapsed, clearMode, textClear, textSend, submitButtonConf]);
const buttonClassName = useMemo(() => {
return `mwai-input-submit ${busy ? 'mwai-busy' : ''}`;
}, [busy]);
const onSubmitClick = useCallback(() => {
if (isListening) {
setIsListening(false);
}
if (clearMode) {
onClear();
} else {
onSubmitAction();
}
}, [clearMode, isListening, onClear, onSubmitAction, setIsListening]);
const handleClick = useCallback(() => {
if (!busy) {
onSubmitClick();
}
}, [busy, onSubmitClick]);
return /*#__PURE__*/React.createElement("button", {
className: buttonClassName,
disabled: busy || isFileUploading || locked,
onClick: handleClick
}, buttonContent);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotSubmit);
/***/ }),
/***/ "./app/js/chatbot/ChatbotSystem.js":
/*!*****************************************!*\
!*** ./app/js/chatbot/ChatbotSystem.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _app_chatbot_ChatbotUI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/chatbot/ChatbotUI */ "./app/js/chatbot/ChatbotUI.js");
const ChatbotSystem = props => {
return /*#__PURE__*/React.createElement(_app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.ChatbotContextProvider, props, /*#__PURE__*/React.createElement(_app_chatbot_ChatbotUI__WEBPACK_IMPORTED_MODULE_1__["default"], props));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotSystem);
/***/ }),
/***/ "./app/js/chatbot/ChatbotTrigger.js":
/*!******************************************!*\
!*** ./app/js/chatbot/ChatbotTrigger.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _ChatbotContext__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../helpers */ "./app/js/helpers.js");
// React & Vendor Libs
const {
useMemo,
useEffect
} = wp.element;
const ChatbotTrigger = () => {
const {
state,
actions
} = (0,_ChatbotContext__WEBPACK_IMPORTED_MODULE_0__.useChatbotContext)();
const {
isWindow,
iconText,
showIconMessage,
iconAlt,
iconUrl,
open
} = state;
const {
setShowIconMessage,
setOpen
} = actions;
useEffect(() => {
if (open && showIconMessage) {
setShowIconMessage(false);
}
}, [open, setShowIconMessage, showIconMessage]);
const triggerContent = useMemo(() => {
if (!isWindow) {
return null;
}
const renderIcon = () => {
if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isEmoji)(iconUrl)) {
return /*#__PURE__*/React.createElement("div", {
className: "mwai-icon mwai-emoji",
style: {
fontSize: '48px',
lineHeight: '64px',
width: '64px',
height: '64px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}
}, iconUrl);
} else {
return /*#__PURE__*/React.createElement("img", {
className: "mwai-icon",
width: "64",
height: "64",
alt: iconAlt,
src: iconUrl
});
}
};
// TODO: Let's remove mwai-open-button at some point.
return /*#__PURE__*/React.createElement("div", {
className: "mwai-trigger mwai-open-button"
}, /*#__PURE__*/React.createElement(_helpers__WEBPACK_IMPORTED_MODULE_2__.TransitionBlock, {
className: "mwai-icon-text-container",
if: iconText && showIconMessage
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-icon-text-close",
onClick: () => setShowIconMessage(false)
}, "\u2715"), /*#__PURE__*/React.createElement("div", {
className: "mwai-icon-text",
onClick: () => setOpen(true)
}, iconText)), /*#__PURE__*/React.createElement("div", {
className: "mwai-icon-container",
onClick: () => setOpen(true)
}, renderIcon()));
}, [isWindow, iconText, showIconMessage, iconAlt, iconUrl, setShowIconMessage, setOpen]);
return /*#__PURE__*/React.createElement(React.Fragment, null, triggerContent);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotTrigger);
/***/ }),
/***/ "./app/js/chatbot/ChatbotUI.js":
/*!*************************************!*\
!*** ./app/js/chatbot/ChatbotUI.js ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/helpers */ "./app/js/chatbot/helpers.js");
/* harmony import */ var _app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/chatbot/ChatbotContext */ "./app/js/chatbot/ChatbotContext.js");
/* harmony import */ var _ChatbotReply__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChatbotReply */ "./app/js/chatbot/ChatbotReply.js");
/* harmony import */ var _ChatbotHeader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ChatbotHeader */ "./app/js/chatbot/ChatbotHeader.js");
/* harmony import */ var _ChatbotTrigger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ChatbotTrigger */ "./app/js/chatbot/ChatbotTrigger.js");
/* harmony import */ var _ChatbotBody__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ChatbotBody */ "./app/js/chatbot/ChatbotBody.js");
// React & Vendor Libs
const {
useState,
useMemo,
useLayoutEffect,
useCallback,
useEffect,
useRef
} = wp.element;
const isImage = file => file.type.startsWith('image/');
const isDocument = file => {
const allowedDocumentTypes = ['text/x-c', 'text/x-csharp', 'text/x-c++', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/html', 'text/x-java', 'application/json', 'text/markdown', 'application/pdf', 'text/x-php', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'text/x-python', 'text/x-script.python', 'text/x-ruby', 'text/x-tex', 'text/plain', 'text/css', 'text/javascript', 'application/x-sh', 'application/typescript'];
return allowedDocumentTypes.includes(file.type);
};
const ChatbotUI = props => {
const css = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.useClasses)();
const {
style
} = props;
const [autoScroll, setAutoScroll] = useState(true);
const {
state,
actions
} = (0,_app_chatbot_ChatbotContext__WEBPACK_IMPORTED_MODULE_1__.useChatbotContext)();
const {
theme,
botId,
customId,
messages,
textCompliance,
isWindow,
fullscreen,
iconPosition,
iconBubble,
shortcuts,
blocks,
imageUpload,
fileSearch,
fileUpload,
draggingType,
isBlocked,
virtualKeyboardFix,
windowed,
cssVariables,
conversationRef,
open,
busy,
uploadIconPosition
} = state;
const {
onSubmit,
setIsBlocked,
setDraggingType,
onUploadFile
} = actions;
const themeStyle = useMemo(() => (theme === null || theme === void 0 ? void 0 : theme.type) === 'css' ? theme === null || theme === void 0 ? void 0 : theme.style : null, [theme]);
const needTools = imageUpload || fileSearch || fileUpload;
const needsFooter = needTools || textCompliance;
const timeoutRef = useRef(null);
// #region Attempt to fix Android & iOS Virtual Keyboard
const {
viewportHeight,
isIOS,
isAndroid
} = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.useViewport)();
useEffect(() => {
if (!virtualKeyboardFix) {
return;
}
if (!(isIOS || isAndroid)) {
return;
}
if (!isWindow) {
return;
}
const scrollableDiv = document.querySelector('.mwai-window');
if (scrollableDiv) {
if (open) {
scrollableDiv.style.height = `${viewportHeight}px`;
if (isIOS) {
const scrollToTop = () => {
if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') {
window.scrollTo({
top: 0
});
// Unfortunately, the first scrollTo doesn't always work, so we need to do it again.
const scrollInterval = setInterval(() => {
window.scrollTo({
top: 0
});
}, 100);
setTimeout(() => {
clearInterval(scrollInterval);
}, 1000);
}
};
scrollToTop();
}
} else {
//console.log("UNSET THE HEIGHT");
scrollableDiv.style.height = '';
}
}
}, [fullscreen, isAndroid, isIOS, isWindow, windowed, open, viewportHeight, virtualKeyboardFix]);
// #endregion
const baseClasses = css('mwai-chatbot', {
[`mwai-${theme === null || theme === void 0 ? void 0 : theme.themeId}-theme`]: true,
'mwai-window': isWindow,
'mwai-bubble': iconBubble,
'mwai-open': open,
'mwai-fullscreen': !windowed || !isWindow && fullscreen,
'mwai-bottom-left': iconPosition === 'bottom-left',
'mwai-top-right': iconPosition === 'top-right',
'mwai-top-left': iconPosition === 'top-left'
});
// #region Auto Scroll
useLayoutEffect(() => {
if (autoScroll && conversationRef.current) {
conversationRef.current.scrollTop = conversationRef.current.scrollHeight;
}
}, [messages, autoScroll, conversationRef, busy]);
const onScroll = () => {
if (conversationRef.current) {
const {
scrollTop,
scrollHeight,
clientHeight
} = conversationRef.current;
const isAtBottom = scrollHeight - scrollTop <= clientHeight + 1; // Allowing a small margin
setAutoScroll(isAtBottom);
}
};
// #endregion
// eslint-disable-next-line no-undef
const executedScripts = useRef(new Set());
const simpleHash = str => {
let hash = 0,
i,
chr;
if (str.length === 0) return hash;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
// Safer executeScript
// const executeScript = (scriptContent) => {
// const scriptHash = simpleHash(scriptContent);
// if (executedScripts.current.has(scriptHash)) {
// return;
// }
// // Wrap in an IIFE + try/catch
// const wrappedCode = `
// (function() {
// try {
// ${scriptContent}
// } catch (err) {
// console.error("User script error:", err);
// }
// })();
// `;
// const script = document.createElement('script');
// script.type = 'text/javascript';
// script.textContent = wrappedCode;
// document.body.appendChild(script);
// executedScripts.current.add(scriptHash);
// };
// Original executeScript
const executeScript = scriptContent => {
const scriptHash = simpleHash(scriptContent);
if (!executedScripts.current.has(scriptHash)) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.textContent = scriptContent;
document.body.appendChild(script);
executedScripts.current.add(scriptHash);
}
};
useEffect(() => {
if (blocks && blocks.length > 0) {
blocks.forEach(block => {
const {
type,
data
} = block;
if (type === 'content' && data.script) {
executeScript(data.script);
}
});
}
}, [blocks]);
const messageList = useMemo(() => messages === null || messages === void 0 ? void 0 : messages.map(message => /*#__PURE__*/React.createElement(_ChatbotReply__WEBPACK_IMPORTED_MODULE_2__["default"], {
key: message.id,
message: message
})), [messages]);
const jsxShortcuts = useMemo(() => {
if (!shortcuts || shortcuts.length === 0) {
return null;
}
return /*#__PURE__*/React.createElement("div", {
className: "mwai-shortcuts"
}, shortcuts.map((action, index) => {
const {
type,
data
} = action;
// Common extraction (label, variant, icon, etc.)
// This part can be repeated or factored out depending on your preference.
const {
label,
variant,
icon,
className
} = data ?? {};
// Base button classes
let baseClasses = css('mwai-shortcut', {
'mwai-success': variant === 'success',
'mwai-danger': variant === 'danger',
'mwai-warning': variant === 'warning',
'mwai-info': variant === 'info'
});
if (className) {
baseClasses += ` ${className}`;
}
// Check icon type
const iconIsURL = icon && icon.startsWith('http');
const iconIsEmoji = icon && !iconIsURL && icon.length >= 1 && icon.length <= 2;
// Use a switch for clarity
switch (type) {
case 'message':
{
// For 'message' type, call onSubmit
const {
message
} = data;
const onClick = () => {
onSubmit(message);
};
return /*#__PURE__*/React.createElement("button", {
className: baseClasses,
key: index,
onClick: onClick
}, (iconIsURL || iconIsEmoji) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-icon"
}, iconIsURL && /*#__PURE__*/React.createElement("img", {
src: icon,
alt: label || "AI Shortcut"
}), iconIsEmoji && /*#__PURE__*/React.createElement("span", {
role: "img",
"aria-label": "AI Shortcut"
}, icon)), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-label"
}, label || "N/A"));
}
case 'callback':
{
// For 'callback' type, call the function in data.onClick
const {
onClick: customOnClick
} = data;
const onClickHandler = () => {
if (typeof customOnClick === 'function') {
customOnClick();
} else if (typeof customOnClick === 'string') {
const replacedOnClick = customOnClick.replace(/{CHATBOT_ID}/g, botId);
const parsedFunction = new Function(`return (${replacedOnClick});`)();
data.onClick = parsedFunction;
parsedFunction();
} else {
console.warn('No valid callback function provided in data.onClick.');
}
};
return /*#__PURE__*/React.createElement("button", {
className: baseClasses,
key: index,
onClick: onClickHandler
}, (iconIsURL || iconIsEmoji) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-icon"
}, iconIsURL && /*#__PURE__*/React.createElement("img", {
src: icon,
alt: label || "AI Shortcut"
}), iconIsEmoji && /*#__PURE__*/React.createElement("span", {
role: "img",
"aria-label": "AI Shortcut"
}, icon)), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-label"
}, label || "N/A"));
}
default:
{
console.warn(`This shortcut type is not supported: ${type}.`);
return null;
}
}
}));
}, [css, onSubmit, shortcuts]);
const jsxBlocks = useMemo(() => {
if (!blocks || blocks.length === 0) {
return null;
}
return /*#__PURE__*/React.createElement("div", {
className: "mwai-blocks"
}, blocks.map((block, index) => {
const {
type,
data
} = block;
if (type !== 'content') {
console.warn(`Block type ${type} is not supported.`);
return null;
}
const {
html,
variant
} = data;
const baseClasses = css('mwai-block', {
'mwai-success': variant === 'success',
'mwai-danger': variant === 'danger',
'mwai-warning': variant === 'warning',
'mwai-info': variant === 'info'
});
return /*#__PURE__*/React.createElement("div", {
className: baseClasses,
key: index,
dangerouslySetInnerHTML: {
__html: html
}
});
}));
}, [css, blocks]);
const handleDrag = useCallback((event, dragState) => {
event.preventDefault();
event.stopPropagation();
const file = event.dataTransfer.items[0];
if (dragState) {
// Clear any existing timeout
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
if (imageUpload && isImage(file)) {
setDraggingType('image');
setIsBlocked(false);
} else if ((fileSearch || fileUpload) && isDocument(file)) {
setDraggingType('document');
setIsBlocked(false);
} else {
setDraggingType(false);
setIsBlocked(true);
}
} else {
// Set a timeout before changing the state
if (!timeoutRef.current) {
timeoutRef.current = setTimeout(() => {
setDraggingType(false);
setIsBlocked(false);
timeoutRef.current = null;
}, 100); // Adjust this delay as needed
}
}
}, [imageUpload, fileSearch, fileUpload]);
const handleDrop = useCallback(event => {
event.preventDefault();
handleDrag(event, false);
if (busy) return;
const file = event.dataTransfer.files[0];
if (file) {
if (draggingType === 'image' && imageUpload) {
onUploadFile(file);
} else if (draggingType === 'document' && (fileSearch || fileUpload)) {
onUploadFile(file);
} else {
// Indicate that the drop is not valid
setIsBlocked(true);
setTimeout(() => setIsBlocked(false), 2000); // Reset after 2 seconds
}
}
}, [busy, draggingType, imageUpload, fileUpload, fileSearch, onUploadFile]);
const inputClassNames = css('mwai-input', {
'mwai-dragging': draggingType,
'mwai-blocked': isBlocked
});
return /*#__PURE__*/React.createElement(_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.TransitionBlock, {
dir: "auto",
id: `mwai-chatbot-${customId || botId}`,
className: baseClasses,
style: {
...cssVariables,
...style
},
if: true,
disableTransition: !isWindow
}, themeStyle && /*#__PURE__*/React.createElement("style", null, themeStyle), /*#__PURE__*/React.createElement(_ChatbotTrigger__WEBPACK_IMPORTED_MODULE_3__["default"], null), /*#__PURE__*/React.createElement(_ChatbotHeader__WEBPACK_IMPORTED_MODULE_4__["default"], null), /*#__PURE__*/React.createElement(_ChatbotBody__WEBPACK_IMPORTED_MODULE_5__["default"], {
conversationRef: conversationRef,
onScroll: onScroll,
messageList: messageList,
jsxShortcuts: jsxShortcuts,
jsxBlocks: jsxBlocks,
inputClassNames: inputClassNames,
handleDrop: handleDrop,
handleDrag: handleDrag,
needsFooter: needsFooter,
needTools: needTools,
uploadIconPosition: uploadIconPosition
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotUI);
/***/ }),
/***/ "./app/js/chatbot/MwaiAPI.js":
/*!***********************************!*\
!*** ./app/js/chatbot/MwaiAPI.js ***!
\***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ addAction: () => (/* binding */ addAction),
/* harmony export */ addFilter: () => (/* binding */ addFilter),
/* harmony export */ applyFilters: () => (/* binding */ applyFilters),
/* harmony export */ doAction: () => (/* binding */ doAction),
/* harmony export */ mwaiAPI: () => (/* binding */ mwaiAPI)
/* harmony export */ });
class MwaiAPI {
constructor() {
if (typeof window !== 'undefined' && window.MwaiAPI) {
return window.MwaiAPI;
}
this.chatbots = [];
this.forms = [];
this.filters = {};
this.actions = {};
if (typeof window !== 'undefined') {
window.MwaiAPI = this;
}
}
getChatbot(botId = null) {
if (!botId) {
return this.chatbots[0];
}
return this.chatbots.find(x => x.botId === botId || x.customId === botId);
}
getForm(formId = null) {
if (!formId) {
return this.forms[0];
}
return this.forms.find(f => f.formId === formId);
}
addFilter(tag, callback, priority = 10) {
if (!this.filters[tag]) {
this.filters[tag] = [];
}
this.filters[tag].push({
callback,
priority
});
this.filters[tag].sort((a, b) => a.priority - b.priority);
}
applyFilters(tag, value, ...args) {
if (!this.filters[tag]) {
return value;
}
return this.filters[tag].reduce((acc, filter) => {
return filter.callback(acc, ...args);
}, value);
}
addAction(tag, callback, priority = 10) {
if (!this.actions[tag]) {
this.actions[tag] = [];
}
this.actions[tag].push({
callback,
priority
});
this.actions[tag].sort((a, b) => a.priority - b.priority);
}
doAction(tag, ...args) {
if (!this.actions[tag]) {
return;
}
this.actions[tag].forEach(action => {
action.callback(...args);
});
}
}
// Ensure the class is only initialized once
const getInstance = () => {
if (typeof window !== 'undefined' && window.MwaiAPI) {
return window.MwaiAPI;
}
const instance = new MwaiAPI();
if (typeof window !== 'undefined') {
window.MwaiAPI = instance;
}
return instance;
};
const mwaiAPI = getInstance();
const addFilter = (tag, callback, priority = 10) => {
mwaiAPI.addFilter(tag, callback, priority);
};
const applyFilters = (tag, value, ...args) => {
return mwaiAPI.applyFilters(tag, value, ...args);
};
const addAction = (tag, callback, priority = 10) => {
mwaiAPI.addAction(tag, callback, priority);
};
const doAction = (tag, ...args) => {
mwaiAPI.doAction(tag, ...args);
};
/***/ }),
/***/ "./app/js/chatbot/helpers.js":
/*!***********************************!*\
!*** ./app/js/chatbot/helpers.js ***!
\***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Microphone: () => (/* binding */ Microphone),
/* harmony export */ TransitionBlock: () => (/* binding */ TransitionBlock),
/* harmony export */ doPlaceholders: () => (/* binding */ doPlaceholders),
/* harmony export */ isURL: () => (/* binding */ isURL),
/* harmony export */ processParameters: () => (/* binding */ processParameters),
/* harmony export */ useChrono: () => (/* binding */ useChrono),
/* harmony export */ useClasses: () => (/* binding */ useClasses),
/* harmony export */ useInterval: () => (/* binding */ useInterval),
/* harmony export */ useSpeechRecognition: () => (/* binding */ useSpeechRecognition),
/* harmony export */ useViewport: () => (/* binding */ useViewport)
/* harmony export */ });
/* harmony import */ var lucide_react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lucide-react */ "./node_modules/lucide-react/dist/esm/icons/mic.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
// React & Vendor Libs
const {
useState,
useMemo,
useEffect,
useRef,
useCallback
} = wp.element;
const Microphone = ({
active,
disabled,
...rest
}) => {
return (
/*#__PURE__*/
// eslint-disable-next-line react/no-unknown-property
React.createElement("div", _extends({
active: active ? "true" : "false",
disabled: disabled
}, rest), /*#__PURE__*/React.createElement(lucide_react__WEBPACK_IMPORTED_MODULE_0__["default"], {
size: "24"
}))
);
};
function useInterval(delay, callback, enabled = true) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null && enabled) {
const id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay, enabled]);
}
const useClasses = () => {
return useMemo(() => {
return (classNames, conditionalClasses) => {
if (!Array.isArray(classNames)) {
classNames = [classNames];
}
if (conditionalClasses) {
Object.entries(conditionalClasses).forEach(([className, condition]) => {
if (condition) {
classNames.push(className);
}
});
}
return classNames.join(' ');
};
}, []);
};
function isURL(url) {
if (!url || typeof url !== 'string') return false;
return url.indexOf('http') === 0;
}
function useChrono() {
const [timeElapsed, setTimeElapsed] = useState(null);
const intervalIdRef = useRef(null);
function startChrono() {
if (intervalIdRef.current !== null) return;
const startTime = Date.now();
intervalIdRef.current = setInterval(() => {
const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);
setTimeElapsed(formatTime(elapsedSeconds));
}, 500);
}
function stopChrono() {
clearInterval(intervalIdRef.current);
intervalIdRef.current = null;
setTimeElapsed(null);
}
function formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
}
useEffect(() => {
return () => {
clearInterval(intervalIdRef.current);
};
}, []);
return {
timeElapsed,
startChrono,
stopChrono
};
}
const doPlaceholders = (text, placeholders) => {
if (typeof text !== 'string' || !placeholders) {
return text;
}
Object.entries(placeholders).forEach(([key, value]) => {
text = text.replace(new RegExp(`{${key}}`, 'g'), value);
});
return text;
};
const processParameters = (params, placeholders = []) => {
var _params$guestName, _params$textSend, _params$textClear, _params$textInputPlac, _params$textComplianc, _params$icon, _params$iconText, _params$iconAlt, _params$iconPosition, _params$aiName, _params$userName, _params$aiAvatarUrl, _params$userAvatarUrl, _params$guestAvatarUr, _params$mode;
const guestName = ((_params$guestName = params.guestName) === null || _params$guestName === void 0 ? void 0 : _params$guestName.trim()) ?? "";
const textSend = ((_params$textSend = params.textSend) === null || _params$textSend === void 0 ? void 0 : _params$textSend.trim()) ?? "";
const textClear = ((_params$textClear = params.textClear) === null || _params$textClear === void 0 ? void 0 : _params$textClear.trim()) ?? "";
const textInputMaxLength = parseInt(params.textInputMaxLength);
const textInputPlaceholder = ((_params$textInputPlac = params.textInputPlaceholder) === null || _params$textInputPlac === void 0 ? void 0 : _params$textInputPlac.trim()) ?? "";
let textCompliance = ((_params$textComplianc = params.textCompliance) === null || _params$textComplianc === void 0 ? void 0 : _params$textComplianc.trim()) ?? "";
let headerSubtitle = "";
const window = Boolean(params.window);
const copyButton = Boolean(params.copyButton);
const fullscreen = Boolean(params.fullscreen);
const icon = ((_params$icon = params.icon) === null || _params$icon === void 0 ? void 0 : _params$icon.trim()) ?? "";
let iconText = ((_params$iconText = params.iconText) === null || _params$iconText === void 0 ? void 0 : _params$iconText.trim()) ?? "";
const iconTextDelay = parseInt(params.iconTextDelay || 1);
const iconAlt = ((_params$iconAlt = params.iconAlt) === null || _params$iconAlt === void 0 ? void 0 : _params$iconAlt.trim()) ?? "";
const iconPosition = ((_params$iconPosition = params.iconPosition) === null || _params$iconPosition === void 0 ? void 0 : _params$iconPosition.trim()) ?? "";
const iconBubble = Boolean(params.iconBubble);
const aiName = ((_params$aiName = params.aiName) === null || _params$aiName === void 0 ? void 0 : _params$aiName.trim()) ?? "";
const userName = ((_params$userName = params.userName) === null || _params$userName === void 0 ? void 0 : _params$userName.trim()) ?? "";
const aiAvatar = Boolean(params === null || params === void 0 ? void 0 : params.aiAvatar);
const userAvatar = Boolean(params === null || params === void 0 ? void 0 : params.userAvatar);
const guestAvatar = Boolean(params === null || params === void 0 ? void 0 : params.guestAvatar);
const aiAvatarUrl = aiAvatar ? (params === null || params === void 0 || (_params$aiAvatarUrl = params.aiAvatarUrl) === null || _params$aiAvatarUrl === void 0 ? void 0 : _params$aiAvatarUrl.trim()) ?? "" : null;
const userAvatarUrl = userAvatar ? (params === null || params === void 0 || (_params$userAvatarUrl = params.userAvatarUrl) === null || _params$userAvatarUrl === void 0 ? void 0 : _params$userAvatarUrl.trim()) ?? "" : null;
const guestAvatarUrl = guestAvatar ? (params === null || params === void 0 || (_params$guestAvatarUr = params.guestAvatarUrl) === null || _params$guestAvatarUr === void 0 ? void 0 : _params$guestAvatarUr.trim()) ?? "" : null;
const localMemory = Boolean(params.localMemory);
const imageUpload = Boolean(params.imageUpload);
const fileUpload = Boolean(params.fileUpload);
const fileSearch = Boolean(params.fileSearch);
const mode = ((_params$mode = params.mode) === null || _params$mode === void 0 ? void 0 : _params$mode.trim()) ?? "chat";
if (params.headerSubtitle === null || params.headerSubtitle === undefined) {
headerSubtitle = "Discuss with";
} else {
var _params$headerSubtitl;
headerSubtitle = ((_params$headerSubtitl = params.headerSubtitle) === null || _params$headerSubtitl === void 0 ? void 0 : _params$headerSubtitl.trim()) ?? "";
}
// This is also executed on the PHP-side, but having this here allows for easier testing in the WP Admin
if (placeholders) {
textCompliance = doPlaceholders(textCompliance, placeholders);
iconText = doPlaceholders(iconText, placeholders);
}
return {
textSend,
textClear,
textInputMaxLength,
textInputPlaceholder,
textCompliance,
mode,
window,
copyButton,
fullscreen,
localMemory,
imageUpload,
fileUpload,
fileSearch,
icon,
iconText,
iconTextDelay,
iconAlt,
iconPosition,
iconBubble,
headerSubtitle,
aiName,
userName,
guestName,
aiAvatar,
userAvatar,
guestAvatar,
aiAvatarUrl,
userAvatarUrl,
guestAvatarUrl
};
};
const isAndroid = () => {
return navigator.userAgent.toLowerCase().indexOf("android") > -1;
};
const useSpeechRecognition = onResult => {
const [isListening, setIsListening] = useState(false);
const [speechRecognitionAvailable, setSpeechRecognitionAvailable] = useState(false);
useEffect(() => {
if (typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)) {
setSpeechRecognitionAvailable(true);
}
}, []);
useEffect(() => {
if (!speechRecognitionAvailable) {
return;
}
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();
let handleResult = null;
if (!isAndroid()) {
recognition.interimResults = true;
recognition.continuous = true;
handleResult = event => {
const transcript = Array.from(event.results).map(result => result[0]).map(result => result.transcript).join('');
onResult(transcript);
};
} else {
recognition.interimResults = false;
recognition.continuous = false;
handleResult = event => {
const finalTranscript = Array.from(event.results).filter(result => result.isFinal).map(result => result[0].transcript).join('');
onResult(finalTranscript);
setIsListening(false);
};
}
if (isListening) {
recognition.addEventListener('result', handleResult);
recognition.start();
} else {
recognition.removeEventListener('result', handleResult);
recognition.abort();
}
return () => {
recognition.abort();
};
}, [isListening, speechRecognitionAvailable]);
return {
isListening,
setIsListening,
speechRecognitionAvailable
};
};
const TransitionBlock = ({
if: condition,
className,
disableTransition = false,
children,
...rest
}) => {
const [shouldRender, setShouldRender] = useState(false);
const [animationClass, setAnimationClass] = useState('mwai-transition');
useEffect(() => {
if (disableTransition) {
setShouldRender(condition);
} else {
if (condition) {
setShouldRender(true);
setTimeout(() => {
setAnimationClass('mwai-transition mwai-transition-visible');
}, 150);
} else {
setAnimationClass('mwai-transition');
}
}
}, [condition, disableTransition]);
const handleTransitionEnd = () => {
if (animationClass === 'mwai-transition' && !disableTransition) {
setShouldRender(false);
}
};
return !shouldRender ? null : /*#__PURE__*/React.createElement("div", _extends({
className: `${className} ${disableTransition ? '' : animationClass}`,
onTransitionEnd: handleTransitionEnd
}, rest), children);
};
const useViewport = () => {
const [viewportHeight, setViewportHeight] = useState(window.visualViewport.height);
const isAndroid = useMemo(() => /Android/.test(navigator.userAgent), []);
const isIOS = useMemo(() => /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream, []);
const viewport = useRef(window.visualViewport);
const handleResize = useCallback(() => {
setViewportHeight(viewport.current.height);
}, []);
useEffect(() => {
const currentViewport = viewport.current;
currentViewport.addEventListener('resize', handleResize);
if (isIOS) {
window.addEventListener('resize', handleResize);
document.addEventListener('focusin', handleResize);
} else {
currentViewport.addEventListener('scroll', handleResize);
}
return () => {
currentViewport.removeEventListener('resize', handleResize);
if (isIOS) {
window.removeEventListener('resize', handleResize);
document.removeEventListener('focusin', handleResize);
} else {
currentViewport.removeEventListener('scroll', handleResize);
}
};
}, [handleResize, isIOS]);
return {
viewportHeight,
isIOS,
isAndroid
};
};
/***/ }),
/***/ "./app/js/components/CopyableField.js":
/*!********************************************!*\
!*** ./app/js/components/CopyableField.js ***!
\********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
// React & Vendor Libs
const {
useState
} = wp.element;
const StyledCopyableField = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
pre {
display: flex;
align-items: center;
background: #f8fcff;
color: #779bb8;
margin: 10px 0 0 0;
padding: 3px 8px;
font-size: 13px;
border: 2px solid rgb(210 228 243);
border-radius: 5px;
font-family: system-ui;
cursor: pointer;
font-weight: 500;
}
.highlight {
color: var(--neko-green);
background: transparent;
}
`;
const CopyableField = ({
children,
value,
...rest
}) => {
const [copyMessage, setCopyMessage] = useState(null);
const onClick = async () => {
if (!navigator.clipboard) {
alert('Clipboard is not enabled (only works with https).');
return;
}
await navigator.clipboard.writeText(value);
setCopyMessage('Copied!');
setTimeout(() => {
setCopyMessage(null);
}, 2000);
};
return /*#__PURE__*/React.createElement(StyledCopyableField, rest, /*#__PURE__*/React.createElement("pre", {
onClick: onClick
}, !copyMessage && children, copyMessage && /*#__PURE__*/React.createElement("span", null, copyMessage)));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CopyableField);
/***/ }),
/***/ "./app/js/components/MCPFunctions.js":
/*!*******************************************!*\
!*** ./app/js/components/MCPFunctions.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useState
} = wp.element;
function MCPFunctions({
options
}) {
const [expandedCategories, setExpandedCategories] = useState({});
// Fetch MCP functions
const {
data: mcpFunctions,
isLoading: functionsLoading,
refetch,
isRefetching
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__.useQuery)({
queryKey: ['mcp-functions', options === null || options === void 0 ? void 0 : options.module_mcp, options === null || options === void 0 ? void 0 : options.mcp_core, options === null || options === void 0 ? void 0 : options.mcp_plugins, options === null || options === void 0 ? void 0 : options.mcp_themes, options === null || options === void 0 ? void 0 : options.mcp_dynamic_rest],
queryFn: async () => {
const response = await fetch(`${window.wpApiSettings.root}mwai/v1/mcp/functions`, {
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': window.wpApiSettings.nonce
}
});
if (!response.ok) throw new Error('Failed to fetch MCP functions');
return response.json();
},
enabled: (options === null || options === void 0 ? void 0 : options.module_mcp) === true,
refetchInterval: false // Disable auto-refresh, use manual refresh instead
});
// Build header buttons
const headerButtons = options !== null && options !== void 0 && options.module_mcp && mcpFunctions !== null && mcpFunctions !== void 0 && mcpFunctions.success && mcpFunctions.count > 0 ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoButton, {
className: "secondary",
onClick: () => refetch(),
disabled: isRefetching
}, isRefetching ? 'Refreshing...' : 'Refresh') : null;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoBlock, {
className: "primary",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.MCP_FUNCTIONS || 'MCP Functions',
action: headerButtons
}, !(options !== null && options !== void 0 && options.module_mcp) ? /*#__PURE__*/React.createElement("p", null, "Enable MCP module to see available functions.") : functionsLoading ? /*#__PURE__*/React.createElement("p", null, "Loading MCP functions...") : mcpFunctions !== null && mcpFunctions !== void 0 && mcpFunctions.success ? /*#__PURE__*/React.createElement(React.Fragment, null, mcpFunctions.count === 0 && !(options !== null && options !== void 0 && options.mcp_core) && !(options !== null && options !== void 0 && options.mcp_themes) && !(options !== null && options !== void 0 && options.mcp_plugins) && !(options !== null && options !== void 0 && options.mcp_dynamic_rest) ? /*#__PURE__*/React.createElement("p", null, _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.MCP_NO_OPTIONS) : /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("strong", null, mcpFunctions.count), " functions are currently registered via MCP."), (mcpFunctions === null || mcpFunctions === void 0 ? void 0 : mcpFunctions.functions) && (() => {
// Group functions by category
const functionsByCategory = mcpFunctions.functions.reduce((acc, func) => {
const category = func.category || 'Others';
if (!acc[category]) {
acc[category] = [];
}
acc[category].push(func);
return acc;
}, {});
// Sort categories with 'Others' at the end
const sortedCategories = Object.keys(functionsByCategory).sort((a, b) => {
if (a === 'Others') return 1;
if (b === 'Others') return -1;
return a.localeCompare(b);
});
return /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10
}
}, sortedCategories.map(category => /*#__PURE__*/React.createElement("div", {
key: category,
style: {
marginBottom: 15
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
borderBottom: '1px solid #e0e0e0',
paddingBottom: 5,
marginBottom: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTypo, {
h4: true,
style: {
margin: 0,
color: '#333'
}
}, category, " (", functionsByCategory[category].length, ")"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoButton, {
size: "small",
className: "secondary",
onClick: () => setExpandedCategories(prev => ({
...prev,
[category]: !prev[category]
}))
}, expandedCategories[category] ? 'Hide Details' : 'Show Details')), expandedCategories[category] && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoAccordions, {
keepState: `mcpFunctionDetails-${category}`
}, functionsByCategory[category].map((func, index) => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoAccordion, {
key: `${category}-${index}`,
title: func.name
}, /*#__PURE__*/React.createElement("div", {
style: {
padding: '10px 0',
color: '#333'
}
}, /*#__PURE__*/React.createElement("p", {
style: {
marginBottom: 10,
color: '#333'
}
}, /*#__PURE__*/React.createElement("strong", null, "Description:"), " ", func.description || 'No description available'), func.inputSchema && /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10,
color: '#333'
}
}, /*#__PURE__*/React.createElement("strong", null, "Arguments:"), /*#__PURE__*/React.createElement("pre", {
style: {
backgroundColor: '#f5f5f5',
padding: 10,
borderRadius: 4,
fontSize: 12,
overflow: 'auto',
marginTop: 5,
color: '#333',
border: '1px solid #ddd'
}
}, JSON.stringify(func.inputSchema, null, 2))), func.outputSchema && /*#__PURE__*/React.createElement("div", {
style: {
color: '#333'
}
}, /*#__PURE__*/React.createElement("strong", null, "Output:"), /*#__PURE__*/React.createElement("pre", {
style: {
backgroundColor: '#f5f5f5',
padding: 10,
borderRadius: 4,
fontSize: 12,
overflow: 'auto',
marginTop: 5,
color: '#333',
border: '1px solid #ddd'
}
}, JSON.stringify(func.outputSchema, null, 2))))))))));
})()) : /*#__PURE__*/React.createElement("p", null, "Failed to load MCP functions.")));
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MCPFunctions);
/***/ }),
/***/ "./app/js/components/NekoColorPicker.js":
/*!**********************************************!*\
!*** ./app/js/components/NekoColorPicker.js ***!
\**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ NekoColorPicker: () => (/* binding */ NekoColorPicker)
/* harmony export */ });
/* harmony import */ var react_colorful__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-colorful */ "./node_modules/react-colorful/dist/index.mjs");
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
const {
useState,
useEffect,
useRef,
useCallback
} = wp.element;
const StyledColorPicker = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
position: relative;
.swatch {
width: 24px;
height: 24px;
border: 3px solid #fff;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.popover {
position: absolute;
top: -210px;
left: -80px;
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
z-index: 9999;
border-radius: 8px;
}
`;
const useClickOutside = (ref, handler) => {
useEffect(() => {
let startedInside = false;
let startedWhenMounted = false;
const listener = event => {
if (startedInside || !startedWhenMounted) return;
if (!ref.current || ref.current.contains(event.target)) return;
handler(event);
};
const validateEventStart = event => {
startedWhenMounted = ref.current;
startedInside = ref.current && ref.current.contains(event.target);
};
document.addEventListener("mousedown", validateEventStart);
document.addEventListener("touchstart", validateEventStart);
document.addEventListener("click", listener);
return () => {
document.removeEventListener("mousedown", validateEventStart);
document.removeEventListener("touchstart", validateEventStart);
document.removeEventListener("click", listener);
};
}, [ref, handler]);
};
const NekoColorPicker = ({
name,
value,
onChange
}) => {
const popover = useRef();
const [isOpen, toggle] = useState(false);
const [color, setColor] = useState(value);
useEffect(() => {
setColor(value);
}, [value]);
const close = useCallback(() => {
if (color !== value) {
onChange(color, name);
}
toggle(false);
}, [color, value]);
useClickOutside(popover, close);
return /*#__PURE__*/React.createElement(StyledColorPicker, {
className: "neko-color-picker"
}, /*#__PURE__*/React.createElement("div", {
className: "swatch",
style: {
backgroundColor: color
},
onClick: () => toggle(true)
}), isOpen && /*#__PURE__*/React.createElement("div", {
className: "popover",
ref: popover,
style: {
background: 'white'
}
}, /*#__PURE__*/React.createElement(react_colorful__WEBPACK_IMPORTED_MODULE_1__.HexColorPicker, {
color: color,
onChange: setColor
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
padding: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoButton, {
style: {
flex: 1
},
onClick: () => onChange(color, name)
}, "Apply"))));
};
/***/ }),
/***/ "./app/js/components/ReplyActions.js":
/*!*******************************************!*\
!*** ./app/js/components/ReplyActions.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/chatbot/helpers */ "./app/js/chatbot/helpers.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const {
useState,
useEffect,
useRef,
useCallback
} = wp.element;
const svgPathDefault = '<path d="M7 5a3 3 0 0 1 3-3h9a3 3 0 0 1 3 3v9a3 3 0 0 1-3 3h-2v2a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3v-9a3 3 0 0 1 3-3h2zm2 2h5a3 3 0 0 1 3 3v5h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-9a1 1 0 0 0-1 1zM5 9a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1z" />';
const svgPathSuccess = '<path d="M10.7673 18C10.3106 18 9.86749 17.8046 9.54432 17.4555L5.50694 13.1222C4.83102 12.3968 4.83102 11.2208 5.50694 10.4954C6.18287 9.76997 7.27871 9.76997 7.95505 10.4954L10.6794 13.4196L16.9621 5.63976C17.5874 4.86495 18.6832 4.78289 19.4031 5.45388C20.125 6.12487 20.2036 7.29638 19.5759 8.07391L12.0778 17.3589C11.7639 17.7475 11.3119 17.9801 10.8319 18C10.8087 18 10.788 18 10.7673 18Z" />';
const svgPathError = '<path d="M17.7623 17.7626C17.0831 18.4418 15.9549 18.416 15.244 17.705L5.79906 8.26012C5.08811 7.54917 5.0623 6.42098 5.74145 5.74183C6.4206 5.06267 7.54879 5.08849 8.25975 5.79944L17.7047 15.2443C18.4156 15.9553 18.4414 17.0835 17.7623 17.7626Z" /><path d="M17.5508 8.52848L8.52842 17.5509C7.84927 18.23 6.72108 18.2042 6.01012 17.4933C5.29917 16.7823 5.27336 15.6541 5.95251 14.975L14.9749 5.95257C15.6541 5.27342 16.7823 5.29923 17.4932 6.01019C18.2042 6.72114 18.23 7.84933 17.5508 8.52848Z" />';
const ReplyActions = ({
enabled,
content,
children,
className,
...rest
}) => {
const css = (0,_app_chatbot_helpers__WEBPACK_IMPORTED_MODULE_0__.useClasses)();
const [copyStatus, setCopyStatus] = useState('idle');
const [hidden, setHidden] = useState(true);
const timeoutRef = useRef(null);
const hasEnteredRef = useRef(false);
const onCopy = () => {
try {
navigator.clipboard.writeText(content);
setCopyStatus('success');
} catch (err) {
setCopyStatus('error');
console.warn('Not allowed to copy to clipboard. Make sure your website uses HTTPS.', {
content
});
} finally {
setTimeout(() => {
setCopyStatus('idle');
}, 2000);
}
};
const handleMouseEnter = useCallback(() => {
if (!hasEnteredRef.current) {
hasEnteredRef.current = true;
timeoutRef.current = setTimeout(() => {
setHidden(false);
}, 500);
}
}, []);
const handleMouseLeave = useCallback(() => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
setHidden(true);
hasEnteredRef.current = false;
}, []);
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
const svgPath = copyStatus === 'success' ? svgPathSuccess : copyStatus === 'error' ? svgPathError : svgPathDefault;
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
onMouseLeave: handleMouseLeave,
onMouseEnter: handleMouseEnter,
onMouseOver: handleMouseEnter
}), /*#__PURE__*/React.createElement("span", {
className: className
}, children), /*#__PURE__*/React.createElement("div", {
className: css('mwai-reply-actions', {
'mwai-hidden': hidden
})
}, enabled && /*#__PURE__*/React.createElement("div", {
className: "mwai-copy-button",
onClick: onCopy
}, /*#__PURE__*/React.createElement("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24",
dangerouslySetInnerHTML: {
__html: svgPath
}
}))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ReplyActions);
/***/ }),
/***/ "./app/js/components/Templates.js":
/*!****************************************!*\
!*** ./app/js/components/Templates.js ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Switch.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Spinner.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../constants */ "./app/js/constants.js");
/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../i18n */ "./app/i18n.js");
const {
useState,
useEffect,
useMemo
} = wp.element;
// Neko UI
// AI Engine
function generateUniqueId() {
return new Date().getTime().toString(36) + Math.random().toString(36).substr(2, 9);
}
// Local storage helpers for template persistence
const TEMPLATE_STORAGE_PREFIX = 'mwai_last_template_';
const TEMPLATE_STORAGE_EXPIRY = 30 * 24 * 60 * 60 * 1000; // 30 days in milliseconds
const saveTemplatePreference = (category, templateId) => {
try {
const key = `${TEMPLATE_STORAGE_PREFIX}${category}`;
const data = {
templateId,
timestamp: Date.now()
};
localStorage.setItem(key, JSON.stringify(data));
} catch (error) {
console.warn('Failed to save template preference:', error);
}
};
const loadTemplatePreference = category => {
try {
const key = `${TEMPLATE_STORAGE_PREFIX}${category}`;
const stored = localStorage.getItem(key);
if (!stored) return null;
const data = JSON.parse(stored);
// Check if the stored preference is expired
if (Date.now() - data.timestamp > TEMPLATE_STORAGE_EXPIRY) {
localStorage.removeItem(key);
return null;
}
return data.templateId;
} catch (error) {
console.warn('Failed to load template preference:', error);
return null;
}
};
const sortTemplates = templates => {
const freshTemplates = [...templates];
freshTemplates.sort((a, b) => {
return a.name.localeCompare(b.name);
});
return freshTemplates;
};
const retrieveTemplates = async category => {
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/system/templates?category=${category}`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce
});
let templates = [];
if (category === 'imagesGenerator') {
templates = _constants__WEBPACK_IMPORTED_MODULE_2__.Templates_ImagesGenerator;
} else if (category === 'playground') {
templates = _constants__WEBPACK_IMPORTED_MODULE_2__.Templates_Playground;
} else if (category === 'contentGenerator') {
templates = _constants__WEBPACK_IMPORTED_MODULE_2__.Templates_ContentGenerator;
}
const defTemplate = templates.find(x => x.id === 'default');
if (res !== null && res !== void 0 && res.templates && res.templates.length > 0) {
templates = sortTemplates(res.templates);
}
// Let's make sure we have all the keys of the default template
if (defTemplate) {
templates.forEach(tpl => {
Object.keys(defTemplate).forEach(key => {
if (typeof tpl[key] === 'undefined') {
tpl[key] = defTemplate[key];
}
});
});
} else {
console.warn("Default template not found for category: " + category);
}
return templates;
} catch (err) {
console.error(err);
alert(err.message);
}
};
const useTemplates = (category = 'playground') => {
const [template, setTemplate] = useState();
const [isEdit, setIsEdit] = useState(false);
const [templates, setTemplates] = useState([]);
const {
isLoading: isLoadingTemplates,
data: newTemplates
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_3__.useQuery)({
queryKey: [`templates-${category}`],
queryFn: () => retrieveTemplates(category)
});
useEffect(() => {
for (let i = 0; i < templates.length; i++) {
const template = templates[i];
let hasChanges = false;
// Only set defaults if envId/model are null/undefined, not empty strings
if (template && (template.envId === null || template.envId === undefined || template.model === null || template.model === undefined)) {
const envId = (_app_settings__WEBPACK_IMPORTED_MODULE_1__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_1__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_1__.options.ai_default_env) || null;
let model = (_app_settings__WEBPACK_IMPORTED_MODULE_1__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_1__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_1__.options.ai_default_model) || null;
if (category === 'imagesGenerator') {
model = 'dall-e-3-hd';
}
if (envId && model) {
template.envId = envId;
template.model = model;
hasChanges = true;
}
}
if (hasChanges) {
setTemplates([...templates]);
}
}
}, [templates]);
useEffect(() => {
if (newTemplates) {
setTemplates(newTemplates);
// Try to load the last selected template from local storage
const savedTemplateId = loadTemplatePreference(category);
let selectedTemplate = null;
if (savedTemplateId) {
selectedTemplate = newTemplates.find(t => t.id === savedTemplateId);
}
// Fall back to default template or first template if saved one not found
if (!selectedTemplate) {
const defTpl = newTemplates.find(t => t.id === 'default');
selectedTemplate = defTpl || newTemplates[0];
}
setTemplate(selectedTemplate);
}
}, [newTemplates, category]);
const saveTemplates = async freshTemplates => {
freshTemplates = sortTemplates(freshTemplates);
setTemplates(freshTemplates);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/system/templates`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
category,
templates: freshTemplates
}
});
return res;
} catch (err) {
console.error(err);
alert(err.message);
}
};
const isDifferent = useMemo(() => {
if (!template || templates.length === 0) {
return false;
}
if (Object.keys(template).length !== Object.keys(templates.find(x => x.id === template.id)).length) {
return true;
}
const originalTpl = templates.find(x => x.id === template.id);
return Object.keys(originalTpl).some(key => originalTpl[key] !== template[key]);
}, [template, templates]);
const updateTemplate = tpl => {
setTemplate(tpl);
// Save the template preference to local storage
if (tpl && tpl.id) {
saveTemplatePreference(category, tpl.id);
}
};
const clearTemplate = () => {
const freshTpl = templates.find(x => x.id === template.id);
if (freshTpl) {
updateTemplate({
...freshTpl
});
}
};
const onSaveAsNewClick = () => {
const newName = prompt(_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.NAME, template.name || _i18n__WEBPACK_IMPORTED_MODULE_4__["default"].TEMPLATES.NEW_TEMPLATE_NAME);
if (!newName) {
return false;
}
const newTpl = {
...template,
id: generateUniqueId(),
name: newName
};
saveTemplates([...templates, newTpl]);
updateTemplate({
...newTpl
});
};
const onSaveClick = () => {
const newTemplates = templates.map(x => {
if (x.id === template.id) {
return template;
}
return x;
});
saveTemplates(newTemplates);
updateTemplate({
...template
});
};
const onNewClick = () => {
const newName = prompt('Template Name', template.name);
const newTpl = {
...templates[0],
id: generateUniqueId(),
name: newName
};
saveTemplates([...templates, newTpl]);
updateTemplate({
...newTpl
});
};
const onRenameClick = () => {
const newName = prompt('Template Name', template.name);
if (!newName) {
return;
}
const newTemplates = templates.map(x => {
if (x.id === template.id) {
return {
...x,
name: newName
};
}
return x;
});
saveTemplates([...newTemplates]);
updateTemplate({
...newTemplates.find(x => x.id === template.id)
});
};
const onResetAllTemplates = () => {
if (!confirm(_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].TEMPLATES.DELETE_ALL_CONFIRM)) {
return;
}
let newTemplates = [];
if (category === 'imagesGenerator') {
newTemplates = [..._constants__WEBPACK_IMPORTED_MODULE_2__.Templates_ImagesGenerator];
} else if (category === 'playground') {
newTemplates = [..._constants__WEBPACK_IMPORTED_MODULE_2__.Templates_Playground];
} else if (category === 'contentGenerator') {
newTemplates = [..._constants__WEBPACK_IMPORTED_MODULE_2__.Templates_ContentGenerator];
}
saveTemplates(newTemplates);
updateTemplate({
...newTemplates[0]
});
};
const onDeleteClick = tpl => {
if (!confirm(_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].TEMPLATES.DELETE_CONFIRM)) {
return;
}
const newTemplates = templates.filter(x => x.id !== tpl.id);
saveTemplates([...newTemplates]);
updateTemplate({
...newTemplates[0]
});
};
const canSave = useMemo(() => {
return isDifferent && !!template;
}, [isDifferent, template]);
const canRename = useMemo(() => {
return template && template.id !== 'default';
}, [template]);
const canDelete = useMemo(() => {
return template && template.id !== 'default';
}, [template]);
const jsxTemplates = useMemo(() => {
return /*#__PURE__*/React.createElement("div", {
style: {
margin: '0'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}
}, /*#__PURE__*/React.createElement("h3", {
style: {
margin: 0
}
}, _i18n__WEBPACK_IMPORTED_MODULE_4__["default"].TEMPLATES.TEMPLATE), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSwitch, {
small: true,
onLabel: _i18n__WEBPACK_IMPORTED_MODULE_4__["default"].TEMPLATES.EDIT,
offLabel: _i18n__WEBPACK_IMPORTED_MODULE_4__["default"].TEMPLATES.EDIT,
width: 60,
onChange: setIsEdit,
checked: isEdit
}))), isLoadingTemplates && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 30,
justifyContent: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
width: 60
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoSpinner, {
width: 20
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), isEdit && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "primary",
style: {
flex: 3
},
onClick: onNewClick
}, "New"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
onClick: onSaveAsNewClick,
style: {
flex: 1
}
}, "Duplicate")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoSelect, {
scrolldown: true,
name: "template",
value: template === null || template === void 0 ? void 0 : template.id,
onChange: value => {
const selectedTemplate = templates.find(x => x.id === value);
updateTemplate({
...selectedTemplate
});
}
}, templates.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
}))), (isDifferent || isEdit) && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "secondary",
style: {
flex: 1
},
disabled: !canSave,
onClick: clearTemplate
}, "Reset"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "primary",
style: {
flex: 3
},
disabled: !canSave,
onClick: onSaveClick
}, "Save")), isEdit && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
small: true,
className: "danger",
style: {
flex: 1
},
disabled: !canDelete,
onClick: () => onDeleteClick(template)
}, "Delete"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
small: true,
className: "secondary",
style: {
flex: 3
},
disabled: !canRename,
onClick: onRenameClick
}, "Rename")))), isEdit && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "danger",
style: {
flex: 1
},
onClick: onResetAllTemplates
}, "Reset All Templates"))));
}, [templates, template, isEdit, isDifferent, canSave, isLoadingTemplates]);
return {
template,
templates,
clearTemplate,
setTemplate: updateTemplate,
jsxTemplates,
isEdit
};
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (useTemplates);
/***/ }),
/***/ "./app/js/components/TokensInfo.js":
/*!*****************************************!*\
!*** ./app/js/components/TokensInfo.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
const {
useMemo
} = wp.element;
const TokensInfo = ({
model,
maxTokens,
onRecommendedClick,
...rest
}) => {
const maxContextualTokens = model === null || model === void 0 ? void 0 : model.maxContextualTokens;
const maxCompletionTokens = model === null || model === void 0 ? void 0 : model.maxCompletionTokens;
const modelMaxTokens = model === null || model === void 0 ? void 0 : model.maxTokens;
const isClickEnabled = !!onRecommendedClick;
maxTokens = Math.floor(parseInt(maxTokens), 0);
const recommendedMaxTokens = useMemo(() => {
if (!model) return null;
if (maxCompletionTokens) {
return maxCompletionTokens;
}
if (maxContextualTokens) {
return Math.floor(maxContextualTokens / 2);
}
if (modelMaxTokens) {
return Math.floor(modelMaxTokens / 2);
}
return null;
}, [maxCompletionTokens, maxContextualTokens, modelMaxTokens]);
const color = useMemo(() => {
if (!model) return null;
if (recommendedMaxTokens === maxTokens) {
return 'var(--neko-green)';
} else if (maxTokens > maxCompletionTokens) {
return 'var(--neko-red)';
}
return 'var(--neko-yellow)';
}, [maxCompletionTokens, maxTokens, recommendedMaxTokens]);
return /*#__PURE__*/React.createElement("span", rest, (!!(model !== null && model !== void 0 && model.maxContextualTokens) || !!(model !== null && model !== void 0 && model.maxCompletionTokens)) && /*#__PURE__*/React.createElement(React.Fragment, null, !!(model !== null && model !== void 0 && model.maxContextualTokens) && /*#__PURE__*/React.createElement(React.Fragment, null, "Contextual: ", model === null || model === void 0 ? void 0 : model.maxContextualTokens), !!(model !== null && model !== void 0 && model.maxContextualTokens) && !!(model !== null && model !== void 0 && model.maxCompletionTokens) && /*#__PURE__*/React.createElement(React.Fragment, null, " - "), !!(model !== null && model !== void 0 && model.maxCompletionTokens) && /*#__PURE__*/React.createElement(React.Fragment, null, "Completion: ", model === null || model === void 0 ? void 0 : model.maxCompletionTokens), /*#__PURE__*/React.createElement("br", null)), !(model !== null && model !== void 0 && model.maxCompletionTokens) && !!(model !== null && model !== void 0 && model.maxTokens) && /*#__PURE__*/React.createElement(React.Fragment, null, "Total Max Tokens: ", model === null || model === void 0 ? void 0 : model.maxTokens, /*#__PURE__*/React.createElement("br", null)), !!recommendedMaxTokens && recommendedMaxTokens !== maxTokens && /*#__PURE__*/React.createElement(React.Fragment, null, "Recommended: ", /*#__PURE__*/React.createElement("b", {
onClick: isClickEnabled ? () => onRecommendedClick(recommendedMaxTokens) : null,
style: {
color: color,
cursor: isClickEnabled ? 'pointer' : 'inherit'
}
}, recommendedMaxTokens, maxTokens > maxCompletionTokens && /*#__PURE__*/React.createElement(React.Fragment, null, "\u2757\uFE0F")), /*#__PURE__*/React.createElement("br", null)));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (TokensInfo);
/***/ }),
/***/ "./app/js/components/UsageCosts.js":
/*!*****************************************!*\
!*** ./app/js/components/UsageCosts.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
// React & Vendor Libs
const {
useState,
useMemo
} = wp.element;
// NekoUI
const UsageCosts = calculatePrice => {
const [sessionCost, setSessionCost] = useState(0);
const [lastCost, setLastCost] = useState(0);
const onReset_usage = () => {
setSessionCost(0);
setLastCost(0);
};
const addUsage = (model, inUnits, outUnits) => {
const cost = calculatePrice(model, inUnits, outUnits);
setLastCost(cost);
setSessionCost(sessionCost + cost);
};
const jsxUsageCosts = useMemo(() => {
let sentence = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.USAGE_HELP);
if (!_app_settings__WEBPACK_IMPORTED_MODULE_2__.isRegistered) {
sentence = /*#__PURE__*/React.createElement(React.Fragment, null, sentence, " ", (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.USAGE_PRO_HELP));
}
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, "Session: ", /*#__PURE__*/React.createElement("span", {
style: {
float: 'right'
}
}, "$", sessionCost.toFixed(4))), /*#__PURE__*/React.createElement("div", null, "Last Request: ", /*#__PURE__*/React.createElement("span", {
style: {
float: 'right'
}
}, "$", lastCost.toFixed(4))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, {
height: 15
}), /*#__PURE__*/React.createElement("p", {
style: {
fontSize: 11,
lineHeight: 1.4,
opacity: 0.6,
margin: 0
}
}, sentence), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, {
height: 15
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
fullWidth: true,
onClick: onReset_usage
}, "Reset Usage"));
}, [sessionCost, lastCost]);
return {
addUsage,
jsxUsageCosts
};
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (UsageCosts);
/***/ }),
/***/ "./app/js/components/UsageWidget.js":
/*!******************************************!*\
!*** ./app/js/components/UsageWidget.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var chart_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! chart.js */ "./node_modules/chart.js/dist/chart.js");
/* harmony import */ var react_chartjs_2__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react-chartjs-2 */ "./node_modules/react-chartjs-2/dist/index.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useState,
useMemo,
Fragment
} = wp.element;
chart_js__WEBPACK_IMPORTED_MODULE_0__.Chart.register(chart_js__WEBPACK_IMPORTED_MODULE_0__.CategoryScale, chart_js__WEBPACK_IMPORTED_MODULE_0__.LinearScale, chart_js__WEBPACK_IMPORTED_MODULE_0__.BarElement, chart_js__WEBPACK_IMPORTED_MODULE_0__.Tooltip, chart_js__WEBPACK_IMPORTED_MODULE_0__.Legend);
const UsageDetails = ({
month,
usageData,
groupBy,
metric
}) => {
if (usageData[month].length === 0) {
return /*#__PURE__*/React.createElement("div", {
style: {
width: 'calc(100% - 36px)',
margin: '5px 18px 0px 18px',
fontStyle: 'italic'
}
}, "No data available.");
}
// Show only queries when Queries metric is selected
if (metric === 'queries') {
return /*#__PURE__*/React.createElement("table", {
style: {
width: 'calc(100% - 36px)',
margin: '5px 18px 0px 18px',
borderCollapse: 'collapse'
}
}, /*#__PURE__*/React.createElement("tbody", null, usageData[month].map((data, index) => {
const formattedQueries = data.queries ? data.queries.toLocaleString() : '0';
// When grouped by family and there are individual models, show them
if (groupBy === 'family' && data.models && data.models.length > 0) {
return /*#__PURE__*/React.createElement(Fragment, {
key: index
}, /*#__PURE__*/React.createElement("tr", {
style: {
fontWeight: 'bold'
}
}, /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, data.name), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right',
paddingRight: 10
}
}, formattedQueries), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right'
}
}, "Queries")), data.models.map((model, modelIndex) => /*#__PURE__*/React.createElement("tr", {
key: `${index}-${modelIndex}`,
style: {
fontSize: '0.9em',
opacity: 0.8
}
}, /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10,
paddingLeft: 20
}
}, "\u21B3 ", model.modelId || model.rawName), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right',
paddingRight: 10
}
}, model.queries ? model.queries.toLocaleString() : '0'), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right'
}
}, "Queries"))));
}
// Default model-based display
const displayLabel = data.name === 'Unknown Model' ? `⚠️ ${data.rawName}` : groupBy === 'model' && data.modelId ? data.modelId : data.name;
return /*#__PURE__*/React.createElement("tr", {
key: index
}, /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, displayLabel), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right',
paddingRight: 10
}
}, formattedQueries), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right'
}
}, "queries"));
})));
}
// Original display for Price and Units metrics
return /*#__PURE__*/React.createElement("table", {
style: {
width: 'calc(100% - 36px)',
margin: '5px 18px 0px 18px',
borderCollapse: 'collapse'
}
}, /*#__PURE__*/React.createElement("tbody", null, usageData[month].map((data, index) => {
const dataType = data.isImage ? 'images' : data.isAudio ? 'seconds' : 'tokens';
const formattedUnits = data.units.toLocaleString();
// When grouped by family and there are individual models, show them
if (groupBy === 'family' && data.models && data.models.length > 0) {
return /*#__PURE__*/React.createElement(Fragment, {
key: index
}, /*#__PURE__*/React.createElement("tr", {
style: {
fontWeight: 'bold'
}
}, /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, data.name), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right',
paddingRight: 10
}
}, formattedUnits), /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, dataType), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right'
}
}, data.price > 0 ? `${data.price.toFixed(4)}$` : '-')), data.models.map((model, modelIndex) => /*#__PURE__*/React.createElement("tr", {
key: `${index}-${modelIndex}`,
style: {
fontSize: '0.9em',
opacity: 0.8
}
}, /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10,
paddingLeft: 20
}
}, "\u21B3 ", model.modelId || model.rawName), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right',
paddingRight: 10
}
}, model.units.toLocaleString()), /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, model.isImage ? 'images' : model.isAudio ? 'seconds' : 'tokens'), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right'
}
}, model.price > 0 ? `${model.price.toFixed(4)}$` : '-'))));
}
// Default model-based display
const displayLabel = data.name === 'Unknown Model' ? `⚠️ ${data.rawName}` : groupBy === 'model' && data.modelId ? data.modelId : data.name;
return /*#__PURE__*/React.createElement("tr", {
key: index
}, /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, displayLabel), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right',
paddingRight: 10
}
}, formattedUnits), /*#__PURE__*/React.createElement("td", {
style: {
paddingRight: 10
}
}, dataType), /*#__PURE__*/React.createElement("td", {
style: {
textAlign: 'right'
}
}, data.price > 0 ? `${data.price.toFixed(4)}$` : '-'));
})));
};
const UsageWidget = ({
options
}) => {
const {
models,
getModel,
calculatePrice
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options, null, true);
const ai_models_usage = options === null || options === void 0 ? void 0 : options.ai_models_usage;
const ai_models_usage_daily = options === null || options === void 0 ? void 0 : options.ai_models_usage_daily;
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.useNekoColors)();
const [groupBy, setGroupBy] = useState('family');
// TODO: After January 2026, let's make "Queries" the default in Usage.
// It's because queries is deterministic haha - unlike token estimates which can vary.
const [metric, setMetric] = useState('price');
const [viewMode, setViewMode] = useState('daily'); // 'monthly' or 'daily'
// Debug logging (commented out for production)
// console.log('=== Usage Widget Debug ===');
// console.log('Current date/time:', new Date().toString());
// console.log('Current timezone:', Intl.DateTimeFormat().resolvedOptions().timeZone);
// console.log('Monthly usage data:', ai_models_usage);
// console.log('Daily usage data:', ai_models_usage_daily);
// console.log('View mode:', viewMode);
const calculateUsageData = () => {
const usageData = {};
const sourceData = viewMode === 'daily' ? ai_models_usage_daily || {} : ai_models_usage || {};
Object.keys(sourceData).forEach(period => {
const periodUsage = sourceData[period];
if (!usageData[period]) usageData[period] = [];
const usageMap = {};
Object.keys(periodUsage).forEach(model => {
const modelUsage = periodUsage[model];
const modelObj = getModel(model);
let inUnits = null;
let outUnits = null;
let isAudio = false;
let isImage = false;
if (modelObj) {
if (modelObj.type === 'image') {
outUnits = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.images) || 0;
isImage = true;
} else if (modelObj.type === 'second') {
outUnits = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.seconds) || 0;
isAudio = true;
} else {
inUnits = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.prompt_tokens) || 0;
outUnits = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.completion_tokens) || 0;
}
} else {
inUnits = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.prompt_tokens) || 0;
outUnits = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.completion_tokens) || 0;
}
const price = modelObj ? calculatePrice(model, inUnits, outUnits) : 0;
const units = isImage ? outUnits : inUnits + outUnits;
const queries = (modelUsage === null || modelUsage === void 0 ? void 0 : modelUsage.queries) || 0;
// Determine the grouping key based on groupBy setting
const groupKey = groupBy === 'family' && modelObj !== null && modelObj !== void 0 && modelObj.family ? modelObj.family : model; // Use the actual model ID as the key when grouping by model
const displayName = groupBy === 'family' && modelObj !== null && modelObj !== void 0 && modelObj.family ? modelObj.family : modelObj ? modelObj.rawName : 'Unknown Model';
if (!usageMap[groupKey]) {
usageMap[groupKey] = {
name: displayName,
rawName: model,
modelId: model,
units: 0,
price: 0,
queries: 0,
isImage,
isAudio,
family: modelObj ? modelObj.family : null,
models: []
};
}
usageMap[groupKey].units += units;
usageMap[groupKey].price += price;
usageMap[groupKey].queries += queries;
// Keep track of individual models when grouping by family
if (groupBy === 'family' && modelObj !== null && modelObj !== void 0 && modelObj.family) {
usageMap[groupKey].models.push({
name: modelObj.rawName,
rawName: model,
modelId: model,
units,
price,
queries,
isImage,
isAudio
});
}
});
usageData[period] = Object.values(usageMap);
usageData[period].sort((a, b) => b.price - a.price);
});
return usageData;
};
const usageData = useMemo(calculateUsageData, [ai_models_usage, ai_models_usage_daily, models, viewMode, groupBy]);
// Generate full time range with empty data for missing periods
const fullRangeUsageData = useMemo(() => {
const now = new Date();
const fullData = {};
if (viewMode === 'daily') {
// Generate last 30 days
for (let i = 29; i >= 0; i--) {
const date = new Date(now);
date.setDate(date.getDate() - i);
// Use local date formatting to match the data keys
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const dateKey = `${year}-${month}-${day}`;
fullData[dateKey] = usageData[dateKey] || [];
}
} else {
// Find the earliest month in the data
const months = Object.keys(usageData).sort();
let earliestDate = now;
if (months.length > 0) {
const [year, month] = months[0].split('-');
earliestDate = new Date(year, month - 1, 1);
}
// Ensure we show at least 12 months including current month
const elevenMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 11, 1);
const startDate = earliestDate < elevenMonthsAgo ? earliestDate : elevenMonthsAgo;
// Generate all months from start date to current month
const currentDate = new Date(startDate);
// Make sure we include the current month
while (currentDate.getFullYear() < now.getFullYear() || currentDate.getFullYear() === now.getFullYear() && currentDate.getMonth() <= now.getMonth()) {
// Use local date formatting to avoid timezone issues
const year = currentDate.getFullYear();
const month = String(currentDate.getMonth() + 1).padStart(2, '0');
const monthKey = `${year}-${month}`;
fullData[monthKey] = usageData[monthKey] || [];
currentDate.setMonth(currentDate.getMonth() + 1);
}
}
return fullData;
}, [usageData, viewMode]);
const chartData = useMemo(() => {
const labels = Object.keys(fullRangeUsageData).sort();
const datasets = [];
const fixedColors = [colors.blue, colors.green, colors.yellow, colors.orange, colors.red, colors.purple];
if (groupBy === 'model') {
models.forEach((model, index) => {
const modelId = model.model;
const modelName = model.rawName;
const data = labels.map(month => {
var _fullRangeUsageData$m;
const monthData = (_fullRangeUsageData$m = fullRangeUsageData[month]) === null || _fullRangeUsageData$m === void 0 ? void 0 : _fullRangeUsageData$m.find(data => data.modelId === modelId || data.rawName === modelId);
if (metric === 'tokens') {
return monthData ? Math.max(monthData.units, 1) : 0;
} else if (metric === 'queries') {
return monthData ? monthData.queries || 0 : 0;
} else {
return monthData ? Math.max(monthData.price, 0.01) : 0;
}
});
if (data.some(value => value > 0)) {
datasets.push({
label: modelName,
data,
backgroundColor: fixedColors[index % fixedColors.length]
});
}
});
// Include "Unknown Model" in the chart data
const unknownModels = labels.map(month => {
var _fullRangeUsageData$m2;
const monthData = (_fullRangeUsageData$m2 = fullRangeUsageData[month]) === null || _fullRangeUsageData$m2 === void 0 ? void 0 : _fullRangeUsageData$m2.filter(data => data.name === 'Unknown Model');
if (metric === 'tokens') {
return monthData.reduce((acc, curr) => acc + Math.max(curr.units, 1), 0);
} else if (metric === 'queries') {
return monthData.reduce((acc, curr) => acc + (curr.queries || 0), 0);
} else {
return monthData.reduce((acc, curr) => acc + Math.max(curr.price, 0.01), 0);
}
});
if (unknownModels.some(value => value > 0)) {
datasets.push({
label: 'Unknown Model',
data: unknownModels,
backgroundColor: 'rgba(128, 128, 128, 0.5)'
});
}
} else if (groupBy === 'family') {
const familyData = {};
labels.forEach(month => {
const monthData = fullRangeUsageData[month] || [];
monthData.forEach(data => {
const familyName = data.name; // When grouped by family, name is already the family
if (familyName) {
if (!familyData[familyName]) {
familyData[familyName] = Array(labels.length).fill(0);
}
let value;
if (metric === 'tokens') {
value = Math.max(data.units, 1);
} else if (metric === 'queries') {
value = data.queries || 0;
} else {
value = Math.max(data.price, 0.01);
}
const monthIndex = labels.indexOf(month);
familyData[familyName][monthIndex] += value;
}
});
});
Object.keys(familyData).forEach((familyName, index) => {
datasets.push({
label: familyName,
data: familyData[familyName],
backgroundColor: fixedColors[index % fixedColors.length]
});
});
}
return {
labels,
datasets
};
}, [fullRangeUsageData, models, groupBy, metric, colors]);
const simplifiedLegendData = useMemo(() => {
const legendCounts = {};
chartData.datasets.forEach(dataset => {
const label = dataset.label;
if (!legendCounts[label]) legendCounts[label] = 0;
dataset.data.forEach(value => {
legendCounts[label] += value;
});
});
const topLabels = Object.entries(legendCounts).sort(([, a], [, b]) => b - a).slice(0, 8).map(([label]) => label);
return chartData.datasets.filter(dataset => topLabels.includes(dataset.label));
}, [chartData]);
const chartOptions = {
plugins: {
legend: {
position: 'bottom',
labels: {
filter: legendItem => simplifiedLegendData.some(dataset => dataset.label === legendItem.text)
}
}
},
responsive: true,
scales: {
x: {
stacked: true
},
y: {
stacked: true
}
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, ai_models_usage && Object.keys(ai_models_usage).length === 0 && /*#__PURE__*/React.createElement("div", {
style: {
fontStyle: 'italic'
}
}, "No data available."), ai_models_usage && Object.keys(ai_models_usage).length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
gap: '12px',
flexWrap: 'wrap'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
gap: '12px',
flexWrap: 'wrap'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoQuickLinks, {
name: "metric",
value: metric,
onChange: setMetric
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Price",
value: "price"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Units",
value: "tokens"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Queries",
value: "queries"
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoQuickLinks, {
name: "groupBy",
value: groupBy,
onChange: setGroupBy
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Family",
value: "family"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Model",
value: "model"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoQuickLinks, {
name: "viewMode",
value: viewMode,
onChange: setViewMode
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Daily",
value: "daily"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Monthly",
value: "monthly"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, {
size: "medium"
}), /*#__PURE__*/React.createElement(react_chartjs_2__WEBPACK_IMPORTED_MODULE_5__.Bar, {
options: chartOptions,
data: chartData
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, {
size: "medium"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoAccordions, {
keepState: "monthlyUsageCategories"
}, Object.keys(fullRangeUsageData).sort().reverse().filter(period => {
// Always show the current month, even if empty
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const currentMonthKey = `${year}-${month}`;
const currentDayKey = now.toISOString().split('T')[0];
if (viewMode === 'monthly' && period === currentMonthKey) {
return true;
}
if (viewMode === 'daily' && period === currentDayKey) {
return true;
}
return fullRangeUsageData[period].length > 0;
}).map((period, index) => {
const periodData = fullRangeUsageData[period] || [];
const isDaily = viewMode === 'daily';
const icon = isDaily ? '📅' : '🗓️';
// Calculate the summary value based on metric
let summaryValue;
if (metric === 'queries') {
const totalQueries = periodData.reduce((acc, curr) => acc + (curr.queries || 0), 0);
summaryValue = `${totalQueries.toLocaleString()} Queries`;
} else {
const totalPrice = periodData.reduce((acc, curr) => acc + curr.price, 0).toFixed(2);
summaryValue = `${totalPrice}$`;
}
// Format the period display
let displayPeriod = period;
if (isDaily) {
const date = new Date(period + 'T00:00:00'); // Add time to avoid timezone issues
displayPeriod = date.toLocaleDateString('en-US', {
weekday: 'short',
month: 'short',
day: 'numeric'
});
}
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoAccordion, {
key: index,
title: `${icon} ${displayPeriod} (${summaryValue})`
}, /*#__PURE__*/React.createElement(UsageDetails, {
month: period,
usageData: fullRangeUsageData,
groupBy: groupBy,
metric: metric
}));
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, {
size: "medium"
}), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: 'var(--neko-small-font-size)',
color: 'var(--neko-gray-60)'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.USAGE_ESTIMATES_NOTE)));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (UsageWidget);
/***/ }),
/***/ "./app/js/constants.js":
/*!*****************************!*\
!*** ./app/js/constants.js ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Templates_ContentGenerator: () => (/* binding */ Templates_ContentGenerator),
/* harmony export */ Templates_ImagesGenerator: () => (/* binding */ Templates_ImagesGenerator),
/* harmony export */ Templates_Playground: () => (/* binding */ Templates_Playground),
/* harmony export */ WritingStyles: () => (/* binding */ WritingStyles),
/* harmony export */ WritingTones: () => (/* binding */ WritingTones)
/* harmony export */ });
const WritingStyles = [{
value: 'informative',
label: 'Informative'
}, {
value: 'descriptive',
label: 'Descriptive'
}, {
value: 'creative',
label: 'Creative'
}, {
value: 'narrative',
label: 'Narrative'
}, {
value: 'persuasive',
label: 'Persuasive'
}, {
value: 'reflective',
label: 'Reflective'
}, {
value: 'argumentative',
label: 'Argumentative'
}, {
value: 'analytical',
label: 'Analytical'
}, {
value: 'evaluative',
label: 'Evaluative'
}, {
value: 'journalistic',
label: 'Journalistic'
}, {
value: 'technical',
label: 'Technical'
}];
const WritingTones = [{
value: 'neutral',
label: 'Neutral'
}, {
value: 'formal',
label: 'Formal'
}, {
value: 'assertive',
label: 'Assertive'
}, {
value: 'cheerful',
label: 'Cheerful'
}, {
value: 'humorous',
label: 'Humorous'
}, {
value: 'informal',
label: 'Informal'
}, {
value: 'inspirational',
label: 'Inspirational'
}, {
value: 'professional',
label: 'Professional'
}, {
value: 'confluent',
label: 'Confluent'
}, {
value: 'emotional',
label: 'Emotional'
}, {
value: 'persuasive',
label: 'Persuasive'
}, {
value: 'supportive',
label: 'Supportive'
}, {
value: 'sarcastic',
label: 'Sarcastic'
}, {
value: 'condescending',
label: 'Condescending'
}, {
value: 'skeptical',
label: 'Skeptical'
}, {
value: 'narrative',
label: 'Narrative'
}, {
value: 'journalistic',
label: 'Journalistic'
}];
const defaultModel = "";
// Shared prompt formats for Content Generator
const defaultTitlePrompt = `Write a title for an article in {LANGUAGE}. Must be between 40 and 60 characters. Write naturally as a human would. Output only the title, no formatting, no Markdown, no special characters.
### TOPIC:
{TOPIC}
### CONTEXT:
{CONTEXT}
Generate a title based on the topic above, taking into account the provided context.`;
const defaultSectionsPrompt = `Write {SECTIONS_COUNT} consecutive headings for an article about "{TITLE}", in {LANGUAGE}. Each heading is between 40 and 60 characters. Format each heading with Markdown (## ). Write naturally as a human would. Output only the headings, nothing else.
### TOPIC:
{TOPIC}
### CONTEXT:
{CONTEXT}
Create headings that align with both the topic and context provided above.`;
const defaultContentPrompt = `Write an article about "{TITLE}" in {LANGUAGE}. Write {PARAGRAPHS_PER_SECTION} paragraphs per heading. Use Markdown for formatting. Add an introduction prefixed by "===INTRO: ", and a conclusion prefixed by "===OUTRO: ". Write naturally as a human would.
### ARTICLE STRUCTURE:
{SECTIONS}
### TOPIC DETAILS:
{TOPIC}
### WRITING CONTEXT:
{CONTEXT}
Write the article following the structure above, incorporating the topic details while adhering to the context guidelines.`;
const defaultExcerptPrompt = `Write an excerpt for an article in {LANGUAGE}. Must be between 40 and 60 characters. Write naturally as a human would. Output only the excerpt, no formatting.
### ARTICLE TITLE:
"{TITLE}"
### TOPIC:
{TOPIC}
### CONTEXT:
{CONTEXT}
Create a compelling excerpt that captures the essence of the article while considering the context.`;
const Templates_Playground = [{
id: 'default',
name: 'Default Template',
mode: 'query',
model: defaultModel,
envId: "",
temperature: 0.8,
stopSequence: '',
maxTokens: 2048,
prompt: ''
}, {
id: 'article_translator',
name: 'Text Translator',
mode: 'query',
model: defaultModel,
envId: "",
temperature: 0.3,
stopSequence: '',
maxTokens: 2048,
prompt: `Translate this article into French:\n\nUchiko is located in Ehime prefecture, in the west of the island. The town was prosperous at the end of the 19th century thanks to its production of very good quality white wax. This economic boom allowed wealthy local merchants to build beautiful properties, whose heritage is still visible throughout the town.\n`
}, {
id: 'restaurant_review',
name: 'Restaurant Review Writer',
mode: 'query',
model: defaultModel,
envId: "",
temperature: 0.8,
stopSequence: '',
maxTokens: 2048,
prompt: 'Write a review for a French restaurant located in Kagurazaka, Tokyo. Looks like an old restaurant, food is traditional, chef is talkative, it is always full. Not expensive, but not fancy.\n'
}, {
id: 'article_corrector',
name: 'Text Corrector',
mode: 'query',
model: defaultModel,
envId: "",
temperature: 0.2,
stopSequence: '',
maxTokens: 2048,
prompt: 'Fix the grammar and spelling mistakes in this text:\n\nI wake up at eleben yesderday, I will go bed eary tonigt.\n'
}, {
id: 'seo_assistant',
name: 'SEO Optimizer',
mode: 'query',
model: defaultModel,
envId: "",
temperature: 0.6,
stopSequence: '',
maxTokens: 1024,
prompt: `For the following article, write a SEO-friendly and short title, keywords for Google, and a short excerpt to introduce it. Use this format:\n\nTitle: \nKeywords: \nExcerpt:\n\nArticle:\nUchiko is located in Ehime prefecture, in the west of the island. The town was prosperous at the end of the 19th century thanks to its production of very good quality white wax. This economic boom allowed wealthy local merchants to build beautiful properties, whose heritage is still visible throughout the town.`
}];
const Templates_ImagesGenerator = [{
id: 'default',
name: 'Default Template',
model: '',
envId: '',
resolution: '',
maxResults: 1,
prompt: ''
}, {
id: 'japan',
name: 'Ghibli Scene',
model: '',
envId: '',
resolution: '',
maxResults: 1,
prompt: 'Create an image in the style of a Ghibli-inspired anime oil painting, depicting a quaint, old house in the Japanese countryside. This house, reminiscent of a traditional izakaya, is surrounded by lush trees and overlooks vibrant rice fields. The scene is bathed in the warm, soft glow of a setting sun, casting gentle shadows and creating a tranquil, nostalgic atmosphere. The composition should be rich in texture, capturing the serene beauty of rural Japan in a whimsical, Ghibli-like manner.'
}, {
id: 'steampunk',
name: 'Steampunk Architecture',
model: '',
envId: '',
resolution: '',
maxResults: 1,
prompt: 'Create an image showcasing steampunk architecture, focusing on the exterior view of a grand theater. The style should reflect award-winning architectural photography from a science fiction magazine. The theater, a masterpiece of steampunk design, combines Victorian influences with futuristic, mechanical elements. Its intricate facade features exposed gears, brass pipes, and steam vents, all integrated into the ornate, classical structure. The building should be set against a dramatic sky, highlighting its unique features and the interplay of light and shadow, capturing the essence of a high-quality, professional architectural photograph.'
}, {
id: 'nyao-illustration',
name: 'Nyao Illustration',
model: '',
envId: '',
resolution: '',
maxResults: 1,
prompt: 'The character is an anthropomorphic cat with a whimsical and endearing design, featuring a blend of white and blue fur. The right side of the cat\'s face has a patch of blue fur that also covers the outer part of the ear, while the left side remains predominantly white, except that the eye is surrounded by a green patch of fur. The tail mirrors this pattern with white fur leading to a blue tip. The character\'s facial expression is joyous, with a wide, open-mouthed smile showcasing a single front tooth and a small, black nose. The cat\'s paws are also white, with defined fingers that suggest human-like dexterity. An orange collar encircles the neck, contrasting with the green and blue tones of the body. This collar is adorned with a blue and white emblem in the center, reminiscent of the WordPress logo. The drawing style of this image can be defined as a digital illustration with a cartoonish and whimsical aesthetic. It features bold outlines, flat colors, and simplified shapes which are typical of contemporary character design aimed at a broad, family-friendly audience. The style is reminiscent of modern vector art, which is often used for web graphics, animation, and media aimed at engaging a casual viewer with its clear, approachable, and vibrant visuals.'
}];
const Templates_ContentGenerator = [{
id: 'default',
name: 'Default Template',
mode: 'single',
topic: "",
topics: "",
context: "",
topicsAreTitles: false,
title: "",
sections: "",
model: defaultModel,
envId: "",
temperature: 0.8,
maxTokens: 2048,
sectionsCount: 2,
paragraphsCount: 3,
language: 'en',
customLanguage: '',
writingStyle: 'creative',
writingTone: 'cheerful',
titlePromptFormat: defaultTitlePrompt,
sectionsPromptFormat: defaultSectionsPrompt,
contentPromptFormat: defaultContentPrompt,
excerptPromptFormat: defaultExcerptPrompt
}, {
id: 'explore_tokyo_offbeat',
name: 'Explore Tokyo Offbeat',
mode: 'single',
topic: "5 hidden Tokyo neighborhoods only locals know: retro Showa-era streets, authentic Edo atmosphere, family-run restaurant alleys, old shopping arcades, quiet residential gems. Write in first person as a Tokyo local sharing secret spots.",
topics: "",
context: "",
topicsAreTitles: false,
title: "",
sections: "",
model: defaultModel,
envId: "",
temperature: 0.8,
maxTokens: 2048,
sectionsCount: 5,
paragraphsCount: 2,
language: 'en',
customLanguage: '',
writingStyle: 'informative',
writingTone: 'informal',
titlePromptFormat: defaultTitlePrompt,
sectionsPromptFormat: defaultSectionsPrompt,
contentPromptFormat: defaultContentPrompt,
excerptPromptFormat: defaultExcerptPrompt
}, {
id: 'cat_blog_bulk',
name: 'Cat Blog Bulk Generator',
mode: 'bulk',
topic: "",
topics: `Why Cats Make Perfect Companions
Understanding Cat Body Language
The Science Behind Purring
Indoor vs Outdoor Cats Debate
Best Cat Breeds for Families
Cat Nutrition Guide
Training Your Cat: Tips and Tricks
Common Cat Health Issues`,
context: "Context: This is for a cat enthusiast blog targeting pet owners and cat lovers. The tone should be friendly, informative, and occasionally playful. Include practical tips, scientific facts, and real-world advice. Each article should be engaging and helpful for cat parents at all experience levels.",
topicsAreTitles: false,
title: "",
sections: "",
model: defaultModel,
envId: "",
temperature: 0.7,
maxTokens: 2048,
sectionsCount: 4,
paragraphsCount: 3,
language: 'en',
customLanguage: '',
writingStyle: 'informative',
writingTone: 'cheerful',
titlePromptFormat: defaultTitlePrompt,
sectionsPromptFormat: defaultSectionsPrompt,
contentPromptFormat: defaultContentPrompt,
excerptPromptFormat: defaultExcerptPrompt
}];
/***/ }),
/***/ "./app/js/constants/streamTypes.js":
/*!*****************************************!*\
!*** ./app/js/constants/streamTypes.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ STREAM_TYPES: () => (/* binding */ STREAM_TYPES),
/* harmony export */ STREAM_VISIBILITY: () => (/* binding */ STREAM_VISIBILITY),
/* harmony export */ getDefaultVisibility: () => (/* binding */ getDefaultVisibility)
/* harmony export */ });
// Define streaming message types (matching PHP constants)
const STREAM_TYPES = {
// Content types
CONTENT: 'content',
// Regular assistant message content
THINKING: 'thinking',
// AI reasoning/thinking process
CODE: 'code',
// Code block content
// Tool/Function types
TOOL_CALL: 'tool_call',
// Starting a tool/function call
TOOL_ARGS: 'tool_args',
// Tool arguments (usually hidden)
TOOL_RESULT: 'tool_result',
// Tool execution result
MCP_DISCOVERY: 'mcp_discovery',
// MCP tools being discovered
// Search/Generation types
WEB_SEARCH: 'web_search',
// Web search in progress
FILE_SEARCH: 'file_search',
// File search in progress
IMAGE_GEN: 'image_gen',
// Image generation in progress
EMBEDDINGS: 'embeddings',
// Embeddings operation
// System types
DEBUG: 'debug',
// Debug information
STATUS: 'status',
// Status updates (queued, processing, etc.)
ERROR: 'error',
// Error messages
WARNING: 'warning',
// Warning messages
TRANSCRIPT: 'transcript',
// Audio transcriptions
// Control types
START: 'start',
// Stream started
END: 'end',
// Stream completed
HEARTBEAT: 'heartbeat' // Keep-alive ping
};
// Message visibility settings
const STREAM_VISIBILITY = {
VISIBLE: 'visible',
// Show to user
HIDDEN: 'hidden',
// Hide from user (debug only)
COLLAPSED: 'collapsed' // Show collapsed/summary view
};
// Helper to determine default visibility for each type
const getDefaultVisibility = type => {
const hiddenTypes = [STREAM_TYPES.TOOL_ARGS, STREAM_TYPES.DEBUG, STREAM_TYPES.HEARTBEAT];
const collapsedTypes = [STREAM_TYPES.THINKING, STREAM_TYPES.MCP_DISCOVERY, STREAM_TYPES.STATUS];
if (hiddenTypes.includes(type)) return STREAM_VISIBILITY.HIDDEN;
if (collapsedTypes.includes(type)) return STREAM_VISIBILITY.COLLAPSED;
return STREAM_VISIBILITY.VISIBLE;
};
/***/ }),
/***/ "./app/js/helpers-admin.js":
/*!*********************************!*\
!*** ./app/js/helpers-admin.js ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ AnthropicIcon: () => (/* binding */ AnthropicIcon),
/* harmony export */ DEFAULT_VECTOR: () => (/* binding */ DEFAULT_VECTOR),
/* harmony export */ ENTRY_BEHAVIORS: () => (/* binding */ ENTRY_BEHAVIORS),
/* harmony export */ ENTRY_TYPES: () => (/* binding */ ENTRY_TYPES),
/* harmony export */ GoogleIcon: () => (/* binding */ GoogleIcon),
/* harmony export */ JsIcon: () => (/* binding */ JsIcon),
/* harmony export */ OpenAiIcon: () => (/* binding */ OpenAiIcon),
/* harmony export */ OptionsCheck: () => (/* binding */ OptionsCheck),
/* harmony export */ PhpIcon: () => (/* binding */ PhpIcon),
/* harmony export */ addFromRemote: () => (/* binding */ addFromRemote),
/* harmony export */ cleanSections: () => (/* binding */ cleanSections),
/* harmony export */ getPostContent: () => (/* binding */ getPostContent),
/* harmony export */ nekoFetch: () => (/* binding */ nekoFetch),
/* harmony export */ randomHash: () => (/* binding */ randomHash),
/* harmony export */ retrieveDiscussions: () => (/* binding */ retrieveDiscussions),
/* harmony export */ retrieveLogsActivity: () => (/* binding */ retrieveLogsActivity),
/* harmony export */ retrieveLogsActivityDaily: () => (/* binding */ retrieveLogsActivityDaily),
/* harmony export */ retrievePostContent: () => (/* binding */ retrievePostContent),
/* harmony export */ retrievePostsCount: () => (/* binding */ retrievePostsCount),
/* harmony export */ retrievePostsIds: () => (/* binding */ retrievePostsIds),
/* harmony export */ retrieveRemoteVectors: () => (/* binding */ retrieveRemoteVectors),
/* harmony export */ retrieveVectors: () => (/* binding */ retrieveVectors),
/* harmony export */ runTasks: () => (/* binding */ runTasks),
/* harmony export */ synchronizeEmbedding: () => (/* binding */ synchronizeEmbedding),
/* harmony export */ tableDateTimeFormatter: () => (/* binding */ tableDateTimeFormatter),
/* harmony export */ tableUserIPFormatter: () => (/* binding */ tableUserIPFormatter),
/* harmony export */ toHTML: () => (/* reexport safe */ _neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML),
/* harmony export */ useLanguages: () => (/* binding */ useLanguages),
/* harmony export */ useModels: () => (/* binding */ useModels)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
// Those helpers are used by the Admin Side.
const {
useMemo,
useState,
useEffect,
useRef
} = wp.element;
// Wrapper for nekoFetch that handles token updates
const nekoFetch = async (url, options) => {
try {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(url, options);
// originalNekoFetch might not throw on HTTP errors, so check the response
if (!response || response.error) {
const errorMessage = (response === null || response === void 0 ? void 0 : response.message) || (response === null || response === void 0 ? void 0 : response.error) || 'Request failed';
// Check if it's an authentication error
if ((response === null || response === void 0 ? void 0 : response.code) === 'rest_cookie_invalid_nonce' || (response === null || response === void 0 ? void 0 : response.code) === 'rest_forbidden') {
throw new Error('Your session has expired. Please refresh the page to continue using AI Engine.');
}
throw new Error(errorMessage);
}
// Check for new token in response
if (response && response.new_token) {
(0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.updateRestNonce)(response.new_token);
console.log('[MWAI] Token refreshed!');
}
return response;
} catch (error) {
// If it's already an Error object, just re-throw it
if (error instanceof Error) {
throw error;
}
// Otherwise, create a proper error
throw new Error(error.message || error.toString() || 'Unknown error occurred');
}
};
const ENTRY_TYPES = {
MANUAL: 'manual',
POST_CONTENT: 'postContent',
POST_FRAGMENT: 'postFragment'
};
const ENTRY_BEHAVIORS = {
CONTEXT: 'context',
REPLY: 'reply'
};
const DEFAULT_VECTOR = {
title: '',
content: '',
refId: null,
type: ENTRY_TYPES.MANUAL,
behavior: ENTRY_BEHAVIORS.CONTEXT
};
const OptionsCheck = ({
options
}) => {
const {
ai_envs
} = options;
// We need at least one environment with a valid key (apikey)
const isAISetup = ai_envs.find(x => x.apikey && x.apikey.length > 0);
const pineconeIsOK = !(options !== null && options !== void 0 && options.module_embeddings) || (options === null || options === void 0 ? void 0 : options.embeddings_envs) && (options === null || options === void 0 ? void 0 : options.embeddings_envs.length) > 0;
return /*#__PURE__*/React.createElement(React.Fragment, null, !isAISetup && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoMessage, {
variant: "danger",
style: {
marginTop: 0,
marginBottom: 25
}
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].SETTINGS.AI_ENV_SETUP)), !pineconeIsOK && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoMessage, {
variant: "danger",
style: {
marginTop: 0,
marginBottom: 25
}
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].SETTINGS.PINECONE_SETUP)));
};
function cleanSections(text) {
if (!text) {
return text;
}
const lines = text.split('\n');
const cleanedLines = lines.map(line => {
line = line.replace(/^\d+\.\s/, '');
if (line.startsWith('"')) {
line = line.slice(1);
if (line.endsWith('"')) {
line = line.slice(0, -1);
}
}
return line;
});
return cleanedLines.filter(x => x).join('\n');
}
const useLanguages = ({
disabled,
options,
language: startLanguage
}) => {
const [currentLanguage, setCurrentLanguage] = useState(startLanguage ?? "en");
const languagesObject = (options === null || options === void 0 ? void 0 : options.languages) || [];
const languages = useMemo(() => {
return Object.keys(languagesObject).map(key => {
return {
value: key,
label: languagesObject[key]
};
});
}, [languagesObject]);
useEffect(() => {
setCurrentLanguage(startLanguage);
}, [startLanguage]);
useEffect(() => {
// Use the language stored in the local storage if it exists
const preferredLanguage = localStorage.getItem('mwai_preferred_language');
if (preferredLanguage && languages.find(l => l.value === preferredLanguage)) {
setCurrentLanguage(preferredLanguage);
return;
}
// Otherwise, try to detect the language from the browser
const detectedLanguage = (document.querySelector('html').lang || navigator.language || navigator.userLanguage).substr(0, 2);
if (languages.find(l => l.value === detectedLanguage)) {
setCurrentLanguage(detectedLanguage);
}
}, []);
const currentHumanLanguage = useMemo(() => {
const systemLanguage = languages.find(l => l.value === currentLanguage);
if (systemLanguage) {
return systemLanguage.label;
}
console.warn("A system language should be set.");
return "English";
}, [currentLanguage, languages]);
const onChange = (value, field) => {
setCurrentLanguage(value, field);
localStorage.setItem('mwai_preferred_language', value);
};
const jsxLanguageSelector = useMemo(() => {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSelect, {
scrolldown: true,
name: "language",
disabled: disabled,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].CONTENT_GENERATOR.CUSTOM_LANGUAGE_HELP),
value: currentLanguage,
onChange: onChange
}, languages.map(lang => {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoOption, {
key: lang.value,
value: lang.value,
label: lang.label
});
}));
}, [currentLanguage, currentHumanLanguage, languages]);
return {
jsxLanguageSelector,
currentLanguage,
currentHumanLanguage
};
};
// This hook allows to retrieve the models and their info based on the environment.
// If no environment is given, the default OpenAI models are returned.
// If allEnvs is true, all the models are returned, from every environment.
const useModels = (options, overrideDefaultEnvId, allEnvs = false) => {
const [model, setModel] = useState(options === null || options === void 0 ? void 0 : options.ai_default_model);
const warnedModelsRef = useRef(new Set());
const envId = overrideDefaultEnvId ? overrideDefaultEnvId : options === null || options === void 0 ? void 0 : options.ai_default_env;
const aiEnvs = (options === null || options === void 0 ? void 0 : options.ai_envs) ?? [];
const allEnvironments = useMemo(() => {
if (allEnvs && options !== null && options !== void 0 && options.ai_envs) {
const fakeEnv = {
fake: true,
finetunes: [],
legacy_finetunes: [],
legacy_finetunes_deleted: [],
finetunes_deleted: [],
deployments: []
};
aiEnvs.forEach(env => {
if (env.finetunes) fakeEnv.finetunes.push(...env.finetunes);
if (env.legacy_finetunes) fakeEnv.legacy_finetunes.push(...env.legacy_finetunes);
if (env.legacy_finetunes_deleted) fakeEnv.legacy_finetunes_deleted.push(...env.legacy_finetunes_deleted);
if (env.finetunes_deleted) fakeEnv.finetunes_deleted.push(...env.finetunes_deleted);
if (env.deployments) fakeEnv.deployments.push(...env.deployments);
});
return fakeEnv;
}
return null;
}, [aiEnvs, allEnvs]);
const env = useMemo(() => {
var _options$ai_envs;
if (allEnvs) return allEnvironments;
if (!envId) {
console.warn("useModels: Environment ID is null. Please provide a valid envId.");
return null;
}
const selectedEnv = options === null || options === void 0 || (_options$ai_envs = options.ai_envs) === null || _options$ai_envs === void 0 ? void 0 : _options$ai_envs.find(x => x.id === envId);
if (!selectedEnv) {
console.warn(`useModels: Environment with ID ${envId} could not be resolved.`, {
envs: aiEnvs,
envId
});
return null;
}
return selectedEnv;
}, [aiEnvs, envId, allEnvs, allEnvironments]);
const deletedFineTunes = useMemo(() => {
let deleted = (env === null || env === void 0 ? void 0 : env.finetunes_deleted) || [];
if (Array.isArray(env === null || env === void 0 ? void 0 : env.legacy_finetunes_deleted)) {
deleted = [...deleted, ...env.legacy_finetunes_deleted];
}
return deleted;
}, [env]);
const getTagStyle = tag => {
const colors = {
deprecated: 'var(--neko-red)',
tuned: 'var(--neko-green)',
preview: 'var(--neko-orange)',
experimental: 'var(--neko-red)'
};
return {
background: colors[tag],
color: 'white',
padding: '3px 4px',
margin: '1px 0px 0px 3px',
borderRadius: 4,
fontSize: 9,
lineHeight: '100%'
};
};
const tagDisplayText = {
deprecated: 'DEPRECATED',
tuned: 'TUNED',
preview: 'PREVIEW',
experimental: 'EXPERIMENTAL'
};
const jsxModelName = (x, isTuned) => {
var _x$tags;
const tag = ((_x$tags = x.tags) === null || _x$tags === void 0 ? void 0 : _x$tags.find(tag => ['deprecated', 'preview', 'experimental'].includes(tag))) || (isTuned ? 'tuned' : '');
return /*#__PURE__*/React.createElement(React.Fragment, null, x.name ?? x.suffix ?? x.model, tag && /*#__PURE__*/React.createElement("small", {
style: getTagStyle(tag)
}, tagDisplayText[tag]));
};
const allModels = useMemo(() => {
let models = [];
if ((env === null || env === void 0 ? void 0 : env.fake) === true) {
// The fake environment basically simulate a merge of all the environments, so we can get all the models.
for (const engine of options.ai_engines) {
if (Array.isArray(engine.models)) {
models = [...models, ...engine.models];
}
}
}
// TODO: Maybe we can simplify/refactor all those conditions...
// And avoid the special cases with Azure and HuggingFace!
else if ((env === null || env === void 0 ? void 0 : env.type) === 'azure') {
// TODO: What if the models would be already added/filtered by the core.php instead?
const engine = options.ai_engines.find(x => x.type === 'openai');
const openAiModels = (engine === null || engine === void 0 ? void 0 : engine.models) ?? [];
models = (openAiModels === null || openAiModels === void 0 ? void 0 : openAiModels.filter(x => {
var _env$deployments;
return (_env$deployments = env.deployments) === null || _env$deployments === void 0 ? void 0 : _env$deployments.find(d => d.model === x.model);
})) ?? [];
} else if ((env === null || env === void 0 ? void 0 : env.type) === 'huggingface') {
var _env$customModels;
models = (env === null || env === void 0 || (_env$customModels = env.customModels) === null || _env$customModels === void 0 ? void 0 : _env$customModels.map(x => {
const tags = x['tags'] ? [...new Set([...x['tags'], 'core', 'chat'])] : ['core', 'chat'];
const features = tags.includes('image') ? 'text-to-image' : 'completion';
return {
model: x.name,
name: x.name,
features: features,
tags: tags,
options: []
};
})) ?? [];
} else {
const engine = options.ai_engines.find(x => x.type === (env === null || env === void 0 ? void 0 : env.type));
models = (engine === null || engine === void 0 ? void 0 : engine.models) ?? [];
}
let fineTunes = (env === null || env === void 0 ? void 0 : env.finetunes) ?? [];
if (Array.isArray(env === null || env === void 0 ? void 0 : env.legacy_finetunes)) {
fineTunes = [...fineTunes, ...env.legacy_finetunes];
}
fineTunes = fineTunes.filter(x => x.status === 'succeeded' && x.model);
models = models.map(x => {
return {
...x,
name: jsxModelName(x),
rawName: x.name
};
});
if (fineTunes.length) {
// Add the finetuned models
models = [...models, ...fineTunes.map(x => {
const features = ['completion'];
const splitted = x.model.split(':');
const family = splitted[0];
return {
model: x.model,
name: jsxModelName(x, true),
rawName: x.suffix,
suffix: x.suffix,
features,
family,
description: "finetuned",
finetuned: true,
tags: ['chat', 'finetune']
};
})];
}
return models;
}, [options, env]);
const models = useMemo(() => {
return allModels.filter(x => !deletedFineTunes.includes(x.model));
}, [allModels, deletedFineTunes]);
const coreModels = useMemo(() => {
return allModels.filter(x => {
var _x$tags2;
return x === null || x === void 0 || (_x$tags2 = x.tags) === null || _x$tags2 === void 0 ? void 0 : _x$tags2.includes('core');
});
}, [allModels]);
const imageModels = useMemo(() => {
return models.filter(x => {
var _x$tags3;
return x === null || x === void 0 || (_x$tags3 = x.tags) === null || _x$tags3 === void 0 ? void 0 : _x$tags3.includes('image');
});
}, [models]);
const embeddingsModels = useMemo(() => {
return models.filter(x => {
var _x$tags4;
return x === null || x === void 0 || (_x$tags4 = x.tags) === null || _x$tags4 === void 0 ? void 0 : _x$tags4.includes('embedding');
});
}, [models]);
const visionModels = useMemo(() => {
return models.filter(x => {
var _x$tags5;
return x === null || x === void 0 || (_x$tags5 = x.tags) === null || _x$tags5 === void 0 ? void 0 : _x$tags5.includes('vision');
});
}, [models]);
const completionModels = useMemo(() => {
return models.filter(x => {
var _x$tags6;
return x === null || x === void 0 || (_x$tags6 = x.tags) === null || _x$tags6 === void 0 ? void 0 : _x$tags6.includes('chat');
});
}, [models]);
const audioModels = useMemo(() => {
return models.filter(x => {
var _x$tags7;
return x === null || x === void 0 || (_x$tags7 = x.tags) === null || _x$tags7 === void 0 ? void 0 : _x$tags7.includes('audio');
});
}, [models]);
const jsonModels = useMemo(() => {
return models.filter(x => {
var _x$tags8;
return x === null || x === void 0 || (_x$tags8 = x.tags) === null || _x$tags8 === void 0 ? void 0 : _x$tags8.includes('json');
});
}, [models]);
const realtimeModels = useMemo(() => {
return models.filter(x => {
var _x$tags9;
return x === null || x === void 0 || (_x$tags9 = x.tags) === null || _x$tags9 === void 0 ? void 0 : _x$tags9.includes('realtime');
});
}, [models]);
const getModel = model => {
if (!model) {
return null;
}
let modelObj = allModels.find(x => x.model === model);
if (modelObj) {
return modelObj;
}
if (model.startsWith('gpt-3.5-turbo-') || model.startsWith('gpt-35-turbo')) {
model = 'gpt-3.5-turbo';
}
// Starts with gpt-4o-mini
else if (model.startsWith('gpt-4o-mini')) {
model = 'gpt-4o-mini';
}
// Starts with gpt-4o
else if (model.startsWith('gpt-4o')) {
model = 'gpt-4o';
}
// Starts with gpt-4
else if (model.startsWith('gpt-4')) {
model = 'gpt-4';
}
// Starts with o1
else if (model.startsWith('o1-preview')) {
model = 'o1-preview';
} else if (model.startsWith('o1-mini')) {
model = 'o1-mini';
} else if (model.startsWith('o1-')) {
model = 'o1';
}
// Handle Claude model variations
else if (model.startsWith('claude-opus-4')) {
model = 'claude-opus-4-20250514';
} else if (model.startsWith('claude-sonnet-4')) {
model = 'claude-sonnet-4-20250514';
} else if (model.startsWith('claude-3-7-sonnet')) {
// Map dated versions to the latest version
model = 'claude-3-7-sonnet-latest';
} else if (model.startsWith('claude-3-5-sonnet-2024')) {
// Keep specific dated versions
if (model === 'claude-3-5-sonnet-20241022') {
model = 'claude-3-5-sonnet-20241022';
} else if (model === 'claude-3-5-sonnet-20240620') {
model = 'claude-3-5-sonnet-20240620';
} else {
model = 'claude-3-5-sonnet-latest';
}
} else if (model.startsWith('claude-3-5-sonnet') || model.startsWith('claude-3.5-sonnet')) {
model = 'claude-3-5-sonnet-latest';
} else if (model.startsWith('claude-3-opus-2024')) {
model = 'claude-3-opus-latest';
} else if (model.startsWith('claude-3-opus')) {
model = 'claude-3-opus-latest';
} else if (model.startsWith('claude-3-sonnet')) {
model = 'claude-3-sonnet-20240229';
} else if (model.startsWith('claude-3-5-haiku')) {
model = 'claude-3-5-haiku-20241022';
} else if (model.startsWith('claude-3-haiku')) {
model = 'claude-3-haiku-20240307';
}
modelObj = allModels.find(x => x.model === model);
if (!modelObj && !warnedModelsRef.current.has(model)) {
console.warn(`Model ${model} not found.`, {
allModels,
options
});
warnedModelsRef.current.add(model);
}
return modelObj;
};
const isFineTunedModel = model => {
const modelObj = getModel(model);
return (modelObj === null || modelObj === void 0 ? void 0 : modelObj.finetuned) || false;
};
const getModelName = (model, raw = false) => {
const modelObj = getModel(model);
if (!modelObj) {
//console.warn(`Model ${model} not found.`, { allModels, options });
return model;
}
if (raw && modelObj) {
return modelObj.rawName;
}
return (modelObj === null || modelObj === void 0 ? void 0 : modelObj.name) || (modelObj === null || modelObj === void 0 ? void 0 : modelObj.model) || model;
};
const getFamilyName = model => {
const modelObj = getModel(model);
return (modelObj === null || modelObj === void 0 ? void 0 : modelObj.family) || null;
};
const getFamilyModel = model => {
const modelObj = getModel(model);
const coreModel = coreModels.find(x => (x === null || x === void 0 ? void 0 : x.family) === (modelObj === null || modelObj === void 0 ? void 0 : modelObj.family));
return coreModel || null;
};
const getPrice = (model, resolution = "1024x1024") => {
const modelObj = getFamilyModel(model);
if ((modelObj === null || modelObj === void 0 ? void 0 : modelObj.type) === 'image') {
if (modelObj !== null && modelObj !== void 0 && modelObj.resolutions) {
const opt = modelObj.resolutions.find(x => x.name === resolution);
return (opt === null || opt === void 0 ? void 0 : opt.price) || null;
}
}
return (modelObj === null || modelObj === void 0 ? void 0 : modelObj.price) || null;
};
const calculatePrice = (model, inUnits, outUnits, resolution = "1024x1024") => {
const modelObj = getFamilyModel(model);
const price = getPrice(model, resolution);
let priceIn = price;
let priceOut = price;
if (typeof price === 'object' && price !== null) {
priceIn = price['in'];
priceOut = price['out'];
}
if (priceIn && priceOut) {
return priceIn * inUnits * modelObj['unit'] + priceOut * outUnits * modelObj['unit'];
}
// TODO: Maybe we should do this better.
//console.warn(`Cannot find price for model ${model}.`);
return 0;
};
return {
allModels,
model,
models,
completionModels,
imageModels,
visionModels,
coreModels,
embeddingsModels,
audioModels,
jsonModels,
realtimeModels,
setModel,
isFineTunedModel,
getModelName,
getFamilyName,
getPrice,
getModel,
calculatePrice
};
};
const retrieveRemoteVectors = async queryParams => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/vectors/remote_list`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: queryParams
});
return res ? {
total: res.total,
vectors: res.vectors
} : {
total: 0,
vectors: []
};
};
const addFromRemote = async (queryParams, signal) => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/vectors/add_from_remote`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: queryParams,
signal
});
return res;
};
const retrieveDiscussions = async chatsQueryParams => {
const params = {
...chatsQueryParams,
offset: (chatsQueryParams.page - 1) * chatsQueryParams.limit
};
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/discussions/list`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: params
});
// Check if there's an error in the response
if (res && res.success === false) {
throw new Error(res.message || 'Failed to retrieve discussions');
}
return res ? {
total: res.total,
chats: res.chats
} : {
total: 0,
chats: []
};
};
const retrieveLogsActivity = async (hours = 24) => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/system/logs/activity`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: {
hours
}
});
return res !== null && res !== void 0 && res.data ? res.data : [];
};
const retrieveLogsActivityDaily = async (days = 31, byModel = false) => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/system/logs/activity_daily`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: {
days,
byModel
}
});
return res !== null && res !== void 0 && res.data ? res.data : [];
};
const retrieveVectors = async queryParams => {
var _queryParams$filters, _queryParams$filters2, _res$vectors;
const isSearch = (queryParams === null || queryParams === void 0 || (_queryParams$filters = queryParams.filters) === null || _queryParams$filters === void 0 ? void 0 : _queryParams$filters.search) !== null;
if ((queryParams === null || queryParams === void 0 || (_queryParams$filters2 = queryParams.filters) === null || _queryParams$filters2 === void 0 ? void 0 : _queryParams$filters2.search) === "") {
return [];
}
if (!queryParams.filters.envId) {
return {
total: 0,
vectors: []
};
}
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/vectors/list`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: queryParams
});
// Sort by score if it is a search
if (isSearch && res !== null && res !== void 0 && (_res$vectors = res.vectors) !== null && _res$vectors !== void 0 && _res$vectors.length) {
const sortedVectors = res.vectors.sort((a, b) => {
var _queryParams$sort;
if ((queryParams === null || queryParams === void 0 || (_queryParams$sort = queryParams.sort) === null || _queryParams$sort === void 0 ? void 0 : _queryParams$sort.by) === 'asc') {
return a.score - b.score;
}
return b.score - a.score;
});
res.vectors = sortedVectors;
}
return res ? {
total: res.total,
vectors: res.vectors
} : {
total: 0,
vectors: []
};
};
const retrievePostsCount = async (postType, postStatus = 'publish') => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/helpers/count_posts?postType=${postType}&postStatus=${postStatus}`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)()
});
return res !== null && res !== void 0 && res.count ? parseInt(res === null || res === void 0 ? void 0 : res.count) : null;
};
const retrievePostsIds = async (postType, postStatus = 'publish') => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/helpers/posts_ids?postType=${postType}&postStatus=${postStatus}`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)()
});
return res !== null && res !== void 0 && res.postIds ? res.postIds : [];
};
const retrievePostContent = async (postType, offset = 0, postId = 0, postStatus = 'publish') => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/helpers/post_content?postType=${postType}&postStatus=${postStatus}&offset=${offset}&postId=${postId}`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)()
});
return res;
};
const runTasks = async () => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/helpers/run_tasks`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST'
});
return res;
};
const synchronizeEmbedding = async ({
vectorId,
postId,
envId
}, signal = null) => {
const res = await nekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/vectors/sync`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_1__.getRestNonce)(),
method: 'POST',
json: {
vectorId,
postId,
envId
},
signal
});
return res;
};
function tableDateTimeFormatter(value) {
let time = new Date(value);
time = new Date(time.getTime() - time.getTimezoneOffset() * 60 * 1000);
const formattedDate = time.toLocaleDateString('ja-JP', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
const formattedTime = time.toLocaleTimeString('ja-JP', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
return /*#__PURE__*/React.createElement(React.Fragment, null, formattedDate, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, formattedTime));
}
function tableUserIPFormatter(userId, ip) {
const formattedIP = ip ? (() => {
const maxLength = 16;
let substr = ip.substring(0, maxLength);
if (substr.length < ip.length) {
if (substr.endsWith('.')) {
substr = substr.slice(0, -1);
}
return substr + "~";
}
return substr;
})() : '';
return /*#__PURE__*/React.createElement("div", null, !userId && /*#__PURE__*/React.createElement(React.Fragment, null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GUEST), userId && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: `/wp-admin/user-edit.php?user_id=${userId}`,
rel: "noreferrer"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.USER, " #", userId)), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", {
style: {
color: 'var(--neko-gray)'
}
}, formattedIP));
}
const randomHash = (length = 6) => {
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
let hash = '';
for (let i = 0; i < length; i++) {
hash += chars[Math.floor(Math.random() * chars.length)];
}
return hash;
};
const OpenAiIcon = ({
size = 14,
disabled = false,
style,
...rest
}) => {
const baseStyle = {
position: 'relative',
top: 2,
borderRadius: 2,
filter: disabled ? 'grayscale(100%)' : 'none'
};
const finalStyle = {
...baseStyle,
...style
};
return /*#__PURE__*/React.createElement("img", _extends({
width: size,
height: size
}, rest, {
style: finalStyle,
alt: "OpenAI",
src: _app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl + '/images/chat-openai.svg'
}));
};
const AnthropicIcon = ({
size = 14,
disabled = false,
style,
...rest
}) => {
const baseStyle = {
position: 'relative',
top: 2,
borderRadius: 2,
filter: disabled ? 'grayscale(100%)' : 'none'
};
const finalStyle = {
...baseStyle,
...style
};
return /*#__PURE__*/React.createElement("img", _extends({
width: size,
height: size
}, rest, {
style: finalStyle,
alt: "Anthropic",
src: _app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl + '/images/chat-anthropic.svg'
}));
};
const GoogleIcon = ({
size = 14,
disabled = false,
style,
...rest
}) => {
const baseStyle = {
position: 'relative',
top: 2,
borderRadius: 2,
filter: disabled ? 'grayscale(100%)' : 'none'
};
const finalStyle = {
...baseStyle,
...style
};
return /*#__PURE__*/React.createElement("img", _extends({
width: size,
height: size
}, rest, {
style: finalStyle,
alt: "Google",
src: _app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl + '/images/chat-google.svg'
}));
};
const JsIcon = ({
size = 14,
disabled = false,
style,
...rest
}) => {
const baseStyle = {
position: 'relative',
top: 2,
borderRadius: 2,
filter: disabled ? 'grayscale(100%)' : 'none'
};
const finalStyle = {
...baseStyle,
...style
};
return /*#__PURE__*/React.createElement("img", _extends({
width: size,
height: size
}, rest, {
style: finalStyle,
alt: "JavaScript",
src: _app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl + '/images/code-js.svg'
}));
};
const PhpIcon = ({
size = 14,
disabled = false,
style,
...rest
}) => {
const baseStyle = {
position: 'relative',
top: 2,
borderRadius: 2,
filter: disabled ? 'grayscale(100%)' : 'none'
};
const finalStyle = {
...baseStyle,
...style
};
return /*#__PURE__*/React.createElement("img", _extends({
width: size,
height: size
}, rest, {
style: finalStyle,
alt: "PHP",
src: _app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl + '/images/code-php.svg'
}));
};
const getPostContent = (currentPositionMarker = null) => {
const {
getBlocks,
getSelectedBlockClientId
} = wp.data.select("core/block-editor");
const {
getEditedPostAttribute
} = wp.data.select("core/editor");
const blocks = getBlocks();
const originalTitle = getEditedPostAttribute('title');
const selectedBlockClientId = getSelectedBlockClientId();
let wholeContent = originalTitle + '\n\n';
blocks.forEach((block, _index) => {
if (currentPositionMarker && block.clientId === selectedBlockClientId) {
wholeContent += currentPositionMarker + '\n\n';
} else {
wholeContent += (block.attributes.content || '') + '\n\n';
}
});
return wholeContent.trim();
};
/***/ }),
/***/ "./app/js/helpers.js":
/*!***************************!*\
!*** ./app/js/helpers.js ***!
\***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ BlinkingCursor: () => (/* binding */ BlinkingCursor),
/* harmony export */ OutputHandler: () => (/* binding */ OutputHandler),
/* harmony export */ isEmoji: () => (/* binding */ isEmoji),
/* harmony export */ mwaiFetch: () => (/* binding */ mwaiFetch),
/* harmony export */ mwaiFetchUpload: () => (/* binding */ mwaiFetchUpload),
/* harmony export */ mwaiHandleRes: () => (/* binding */ mwaiHandleRes),
/* harmony export */ nekoStringify: () => (/* binding */ nekoStringify),
/* harmony export */ randomStr: () => (/* binding */ randomStr)
/* harmony export */ });
/* harmony import */ var markdown_to_jsx__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! markdown-to-jsx */ "./node_modules/markdown-to-jsx/dist/index.modern.js");
// React & Vendor Libs
const {
useMemo,
useEffect,
useState
} = wp.element;
// Those helpers don't used any external libraries except Markdown.
// They should be as light as possible.
// Can be used this way:
// const streamCallback = !stream ? null : (content) => {
// // The whole content !
// };
// const res = await mwaiFetch(`${restUrl}/mwai-ui/v1/chats/submit`, body, restNonce, stream);
// const data = await mwaiHandleRes(res, streamCallback, debugMode ? "CHATBOT" : null);
// // data contains { success: true, reply } or { success: false, message }
function nekoStringify(obj, space = null, ignoreCircular = true) {
const cache = [];
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (cache.includes(value)) {
if (!ignoreCircular) {
console.warn('Circular reference found.', {
key,
value,
cache,
cacheIndex: cache.indexOf(value)
});
throw new Error('Circular reference found. Cancelled.');
}
return;
}
cache.push(value);
}
return value;
}, space);
}
async function mwaiHandleRes(fetchRes, onStream, debugName = null, onTokenUpdate = null, debugMode = false) {
// Regular
if (!onStream) {
try {
const data = await fetchRes.json();
if (debugName) {
console.log(`[${debugName}] IN: `, data);
}
// Check for new token in response
if (data.new_token) {
// Log token update if debug mode is enabled
if (debugMode) {
console.log('[MWAI] Token refreshed!');
}
if (onTokenUpdate) {
onTokenUpdate(data.new_token);
}
}
return data;
} catch (err) {
console.error("Could not parse the regular response.", {
err,
data
});
return {
success: false,
message: "Could not parse the regular response."
};
}
}
// Stream
const reader = fetchRes.body.getReader();
const decoder = new TextDecoder('utf-8');
let buffer = '';
let decodedContent = '';
while (true) {
const {
value,
done
} = await reader.read();
buffer += decoder.decode(value, {
stream: true
});
if (done) break;
const lines = buffer.split('\n');
for (let i = 0; i < lines.length - 1; i++) {
if (lines[i].indexOf('data: ') !== 0) {
continue;
}
const data = JSON.parse(lines[i].replace('data: ', ''));
if (data['type'] === 'live') {
if (debugName) {
console.log(`[${debugName} STREAM] LIVE: `, data);
}
// Handle enhanced stream messages
if (data.subtype) {
// New enhanced message format - pass full data object
onStream && onStream(decodedContent, data);
// Only accumulate content for actual content messages
if (data.subtype === 'content') {
decodedContent += data.data;
}
} else {
// Legacy format - accumulate and pass raw data
decodedContent += data.data;
onStream && onStream(decodedContent, data.data);
}
} else if (data['type'] === 'error') {
try {
if (debugName) {
console.error(`[${debugName} STREAM] ERROR: `, data.data);
}
return {
success: false,
message: data.data
};
} catch (err) {
console.error("Could not parse the 'error' stream.", {
err,
data
});
return {
success: false,
message: "Could not parse the 'error' stream."
};
}
} else if (data['type'] === 'end') {
try {
const finalData = JSON.parse(data.data);
if (debugName) {
console.log(`[${debugName} STREAM] END: `, finalData);
}
// Check for new token in streaming response
if (finalData.new_token) {
// Log token update if debug mode is enabled
if (debugMode) {
console.log('[MWAI] Token refreshed!');
}
if (onTokenUpdate) {
onTokenUpdate(finalData.new_token);
}
}
return finalData;
} catch (err) {
console.error("Could not parse the 'end' stream.", {
err,
data
});
return {
success: false,
message: "Could not parse the 'end' stream."
};
}
}
}
buffer = lines[lines.length - 1];
}
try {
const finalData = JSON.parse(buffer);
if (debugName) {
console.log(`[${debugName} STREAM] IN: `, finalData);
}
return finalData;
} catch (err) {
console.error("Could not parse the buffer.", {
err,
buffer
});
return {
success: false,
message: "Could not parse the buffer."
};
}
}
async function mwaiFetch(url, body, restNonce, isStream, signal = undefined, onTokenUpdate = null) {
const headers = {
'Content-Type': 'application/json'
};
if (restNonce) {
headers['X-WP-Nonce'] = restNonce;
}
if (isStream) {
headers['Accept'] = 'text/event-stream';
}
const response = await fetch(`${url}`, {
method: 'POST',
headers,
body: nekoStringify(body),
credentials: 'same-origin',
signal
});
// Check for authentication errors
if (response.status === 403 || response.status === 401) {
try {
const errorData = await response.clone().json();
if (errorData.code === 'rest_cookie_invalid_nonce' || errorData.code === 'rest_forbidden') {
// Token has expired - user needs to refresh the page
console.error('[MWAI] Authentication token has expired. Please refresh the page to continue.');
throw new Error('Your session has expired. Please refresh the page to continue using AI Engine.');
}
} catch (e) {
// If it's not our error format, continue with the original error
if (e.message && e.message.includes('session has expired')) {
throw e;
}
}
}
// For non-streaming responses, check for new token immediately
if (!isStream && response.ok) {
try {
const clonedResponse = response.clone();
const data = await clonedResponse.json();
if (data.new_token && onTokenUpdate) {
onTokenUpdate(data.new_token);
}
} catch (e) {
// If parsing fails, continue normally
}
}
return response;
}
async function mwaiFetchUpload(url, file, restNonce, onProgress, params = {}) {
return new Promise((resolve, reject) => {
const formData = new FormData();
formData.append('file', file);
for (const [key, value] of Object.entries(params)) {
formData.append(key, value);
}
const xhr = new XMLHttpRequest();
// Set up any headers here
xhr.open('POST', url, true);
if (restNonce) {
xhr.setRequestHeader('X-WP-Nonce', restNonce);
}
// Handle progress events
xhr.upload.onprogress = function (event) {
if (event.lengthComputable && onProgress) {
const percentComplete = event.loaded / event.total * 100;
onProgress(percentComplete); // Call the onProgress callback
}
};
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const jsonResponse = JSON.parse(xhr.responseText);
resolve(jsonResponse);
} catch (error) {
reject({
status: xhr.status,
statusText: xhr.statusText,
error: 'The server response is not valid JSON'
});
}
} else {
// Actually, the server might have returned the error message in JSON format, with a success and a message.
// So we try to parse it.
try {
const jsonResponse = JSON.parse(xhr.responseText);
reject({
status: xhr.status,
message: jsonResponse.message
});
return;
} catch (error) {
// Not a JSON, so we continue.
}
reject({
status: xhr.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: xhr.status,
statusText: xhr.statusText
});
};
xhr.send(formData);
});
}
function randomStr() {
return Math.random().toString(36).substring(2);
}
/**
* Simulates a blinking cursor.
*
* @component
* @returns {JSX.Element} A styled span element that represents the cursor.
*/
const BlinkingCursor = () => {
const [visible, setVisible] = useState(true);
useEffect(() => {
const timeout = setTimeout(() => {
const timer = setInterval(() => {
setVisible(v => !v);
}, 500);
return () => clearInterval(timer); // Clean up on component unmount
}, 200);
return () => clearTimeout(timeout);
}, []);
const cursorStyle = {
opacity: visible ? 1 : 0,
width: '1px',
height: '1em',
borderLeft: '8px solid',
marginLeft: '2px'
};
return /*#__PURE__*/React.createElement("span", {
style: cursorStyle
});
};
/**
* Handle the output from the AI, and display it in a proper way (markdown, streaming, etc).
*
* @component
* @param {Object} props - Props passed to the component.
* @param {string} props.content - Markdown content to be processed.
* @param {string} props.error - Error messages, if any.
* @param {boolean} props.isStreaming - A flag indicating if the content is streaming.
* @param {string} props.baseClass - The base CSS class for styling the component, defaults to "mwai-output-handler".
*
* @returns {JSX.Element} A Markdown element with processed content and appropriate classes.
*/
const OutputHandler = props => {
const {
content,
error,
isStreaming,
baseClass = "mwai-output-handler"
} = props;
const isError = !!error;
let data = (isError ? error : content) ?? "";
// Ensure this is encloded markdown
const matches = (data.match(/```/g) || []).length;
if (matches % 2 !== 0) {
// if count is odd
data += "\n```"; // add ``` at the end
} else if (isStreaming) {
data += "<BlinkingCursor />";
}
const classes = useMemo(() => {
const freshClasses = [baseClass];
if (error) {
freshClasses.push('mwai-error');
}
return freshClasses;
}, [error]);
const markdownOptions = useMemo(() => {
const options = {
wrapper: 'div',
forceWrapper: true,
overrides: {
BlinkingCursor: {
component: BlinkingCursor
},
a: {
props: {
target: "_blank"
}
}
}
};
return options;
}, []);
return /*#__PURE__*/React.createElement(markdown_to_jsx__WEBPACK_IMPORTED_MODULE_0__["default"], {
options: markdownOptions,
className: classes.join(' '),
children: data
});
};
const emojiRegex = /([\u2700-\u27BF]|[\uE000-\uF8FF]|[\uD800-\uDFFF]|[\uFE00-\uFE0F]|[\u1F100-\u1F1FF]|[\u1F200-\u1F2FF]|[\u1F300-\u1F5FF]|[\u1F600-\u1F64F]|[\u1F680-\u1F6FF]|[\u1F700-\u1F77F]|[\u1F780-\u1F7FF]|[\u1F800-\u1F8FF]|[\u1F900-\u1F9FF]|[\u1FA00-\u1FA6F])/;
function isEmoji(str) {
return str && str.length === 2 && emojiRegex.test(str);
}
/***/ }),
/***/ "./app/js/helpers/RealtimeEventEmitter.js":
/*!************************************************!*\
!*** ./app/js/helpers/RealtimeEventEmitter.js ***!
\************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../constants/streamTypes */ "./app/js/constants/streamTypes.js");
/**
* RealtimeEventEmitter - A clean helper for emitting stream events in the Realtime API
*
* This class provides a simple interface for emitting stream events that are
* compatible with the existing stream event system used in text-based chats.
*/
class RealtimeEventEmitter {
constructor(onEvent, eventLogsEnabled = false) {
this.onEvent = onEvent;
this.eventLogsEnabled = eventLogsEnabled;
this.sessionStartTime = null;
}
/**
* Emit a stream event if event logs are enabled and callback is available
*/
emit(subtype, data, metadata = {}) {
if (!this.eventLogsEnabled || !this.onEvent) return;
const event = {
type: 'event',
subtype,
data,
timestamp: new Date().getTime(),
...metadata
};
this.onEvent('', event);
}
// Session lifecycle events
sessionStarting() {
this.sessionStartTime = new Date().getTime();
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, 'Starting realtime session...');
}
sessionConnected() {
const duration = this.sessionStartTime ? new Date().getTime() - this.sessionStartTime : 0;
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, `Realtime session connected in ${duration}ms.`);
}
sessionEnding() {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, 'Ending realtime session...');
}
sessionError(error) {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.ERROR, `Realtime session error: ${error}`);
}
// Audio events
userStartedSpeaking() {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, 'User speaking...', {
visibility: 'collapsed'
});
}
userStoppedSpeaking() {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, 'User finished speaking.', {
visibility: 'collapsed'
});
}
assistantStartedSpeaking() {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, 'Assistant speaking...', {
visibility: 'collapsed'
});
}
assistantStoppedSpeaking() {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, 'Assistant finished speaking.', {
visibility: 'collapsed'
});
}
// Function calling events
functionCalling(name, args) {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.TOOL_CALL, `Calling ${name}...`, {
metadata: {
tool_name: name,
arguments: args
}
});
}
functionResult(name, result) {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.TOOL_RESULT, `Got result from ${name}.`, {
metadata: {
tool_name: name,
result
}
});
}
functionError(name, error) {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.ERROR, `Function ${name} failed: ${error}`, {
metadata: {
tool_name: name
}
});
}
// Transcription events
userTranscribed(text) {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, `User: "${text}"`, {
visibility: 'collapsed'
});
}
assistantTranscribed(text) {
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, `Assistant: "${text}"`, {
visibility: 'collapsed'
});
}
// Statistics event
usageUpdated(stats) {
const {
text_input_tokens,
audio_input_tokens,
text_output_tokens,
audio_output_tokens
} = stats;
const total = text_input_tokens + audio_input_tokens + text_output_tokens + audio_output_tokens;
this.emit(_constants_streamTypes__WEBPACK_IMPORTED_MODULE_0__.STREAM_TYPES.STATUS, `Tokens used: ${total} (Text: ${text_input_tokens}/${text_output_tokens}, Audio: ${audio_input_tokens}/${audio_output_tokens})`, {
visibility: 'collapsed',
metadata: {
usage: stats
}
});
}
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (RealtimeEventEmitter);
/***/ }),
/***/ "./app/js/helpers/tokenManager.js":
/*!****************************************!*\
!*** ./app/js/helpers/tokenManager.js ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
// Global token manager to share REST nonce across all components
class TokenManager {
constructor() {
this.token = null;
this.listeners = new Set();
}
setToken(token) {
if (this.token !== token) {
this.token = token;
this.notifyListeners();
}
}
getToken() {
return this.token;
}
subscribe(listener) {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
notifyListeners() {
this.listeners.forEach(listener => listener(this.token));
}
}
// Create a singleton instance
const tokenManager = new TokenManager();
// Initialize with the global token if available
if (typeof window !== 'undefined' && window.mwai && window.mwai.rest_nonce) {
tokenManager.setToken(window.mwai.rest_nonce);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (tokenManager);
/***/ }),
/***/ "./app/js/index.js":
/*!*************************!*\
!*** ./app/js/index.js ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/query-core/build/modern/queryClient.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @common */ "./common/js/dashboard/Dashboard.js");
/* harmony import */ var _settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./settings */ "./app/js/settings.js");
/* harmony import */ var _app_screens_Settings__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @app/screens/Settings */ "./app/js/screens/Settings.js");
/* harmony import */ var _app_screens_Playground__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @app/screens/Playground */ "./app/js/screens/Playground.js");
/* harmony import */ var _modules_PostsListTools__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./modules/PostsListTools */ "./app/js/modules/PostsListTools.js");
/* harmony import */ var _screens_ContentGenerator__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./screens/ContentGenerator */ "./app/js/screens/ContentGenerator.js");
/* harmony import */ var _screens_ImageGenerator__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./screens/ImageGenerator */ "./app/js/screens/ImageGenerator.js");
/* harmony import */ var _modules_BlockFeatures__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/BlockFeatures */ "./app/js/modules/BlockFeatures.js");
/* harmony import */ var _modules_BlockCopilot__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modules/BlockCopilot */ "./app/js/modules/BlockCopilot.js");
/* harmony import */ var _blocks_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./blocks/index */ "./app/js/blocks/index.js");
const {
render
} = wp.element;
const queryClient = new _tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__.QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
refetchOnMount: false,
retry: false,
placeholderData: prev => prev
}
}
});
// Neko UI
// Components
// Gutenberg Blocks
const chatbotsEnabled = _settings__WEBPACK_IMPORTED_MODULE_1__.options.module_chatbots;
const assistantsEnabled = _settings__WEBPACK_IMPORTED_MODULE_1__.options.module_suggestions;
const formsEnabled = _settings__WEBPACK_IMPORTED_MODULE_1__.options.module_forms;
if (chatbotsEnabled) {
(0,_blocks_index__WEBPACK_IMPORTED_MODULE_2__.initChatbotBlocks)();
}
if (formsEnabled) {
// TODO: July 5th, why this is here? Let's comment it out for now.
//initChatbotBlocks();
(0,_blocks_index__WEBPACK_IMPORTED_MODULE_2__.initFormsBlocks)();
}
if (assistantsEnabled) {
(0,_modules_BlockFeatures__WEBPACK_IMPORTED_MODULE_3__["default"])();
(0,_modules_BlockCopilot__WEBPACK_IMPORTED_MODULE_4__["default"])();
}
document.addEventListener('DOMContentLoaded', function () {
// Settings
const settings = document.getElementById('mwai-admin-settings');
if (settings) {
render( /*#__PURE__*/React.createElement(_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.QueryClientProvider, {
client: queryClient
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__["default"], null, /*#__PURE__*/React.createElement(_app_screens_Settings__WEBPACK_IMPORTED_MODULE_7__["default"], null))), settings);
}
// Content Generator
const generator = document.getElementById('mwai-content-generator');
if (generator) {
render( /*#__PURE__*/React.createElement(_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.QueryClientProvider, {
client: queryClient
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__["default"], null, /*#__PURE__*/React.createElement(_screens_ContentGenerator__WEBPACK_IMPORTED_MODULE_8__["default"], null))), generator);
}
// Image Generator
const imgGen = document.getElementById('mwai-image-generator');
if (imgGen) {
render( /*#__PURE__*/React.createElement(_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.QueryClientProvider, {
client: queryClient
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__["default"], null, /*#__PURE__*/React.createElement(_screens_ImageGenerator__WEBPACK_IMPORTED_MODULE_9__["default"], null))), imgGen);
}
// Dashboard
const dashboard = document.getElementById('mwai-playground');
if (dashboard) {
render( /*#__PURE__*/React.createElement(_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.QueryClientProvider, {
client: queryClient
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__["default"], null, /*#__PURE__*/React.createElement(_app_screens_Playground__WEBPACK_IMPORTED_MODULE_10__["default"], null))), dashboard);
}
// Admin Tools
if (assistantsEnabled) {
const postsListTools = document.getElementById('mwai-admin-postsList');
if (postsListTools) {
render( /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__["default"], null, /*#__PURE__*/React.createElement(_modules_PostsListTools__WEBPACK_IMPORTED_MODULE_11__["default"], null)), postsListTools);
}
}
// Common
const meowDashboard = document.getElementById('meow-common-dashboard');
if (meowDashboard) {
render( /*#__PURE__*/React.createElement(_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.QueryClientProvider, {
client: queryClient
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__["default"], null, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_12__.Dashboard, null))), meowDashboard);
}
});
/***/ }),
/***/ "./app/js/modules/BlockCopilot.js":
/*!****************************************!*\
!*** ./app/js/modules/BlockCopilot.js ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _styles_AiIcon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../styles/AiIcon */ "./app/js/styles/AiIcon.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/* eslint-disable react/display-name */
// React & Vendor Libs
const {
addFilter
} = wp.hooks;
const {
useState,
useRef,
useEffect
} = wp.element;
const {
TextControl,
Spinner,
ProgressBar,
ToggleControl,
Card,
CardBody
} = wp.components;
const {
dispatch
} = wp.data;
// NekoUI
// AI Engine
const SHORTCUT_NAME = 'mwai-copilot/prevent-new-block';
const BlockCopilot = () => {
const EnhancedParagraphBlock = props => {
const aiTextControlRef = useRef();
const [display, setDisplay] = useState(false);
const [query, setQuery] = useState('');
const [busy, setBusy] = useState(false);
const [composing, setComposing] = useState(false);
const [isImageMode, setIsImageMode] = useState(false);
const postId = wp.data.select('core/editor').getCurrentPostId();
const handleKeyPress = e => {
var _e$target, _e$target2;
if (composing) return;
const actualContent = ((e === null || e === void 0 || (_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.innerText) || '').trim();
const localName = e === null || e === void 0 || (_e$target2 = e.target) === null || _e$target2 === void 0 ? void 0 : _e$target2.localName;
if (e.code === 'Space' && !actualContent && localName === 'p') {
e.preventDefault();
setDisplay(true);
}
};
const executeQuery = async query => {
const context = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.getPostContent)("[== CURRENT BLOCK ==]");
try {
setBusy(true);
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/ai/copilot`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
json: {
action: isImageMode ? 'image' : 'text',
message: query,
context,
postId
}
});
if (isImageMode) {
const {
media
} = res.data;
const {
createBlock
} = wp.blocks;
const {
replaceBlock
} = wp.data.dispatch('core/block-editor');
const {
getSelectedBlockClientId
} = wp.data.select('core/block-editor');
const imageBlock = createBlock('core/image', {
id: media.id,
url: media.url,
title: media.title,
caption: media.caption,
alt: media.alt
});
const selectedBlockClientId = getSelectedBlockClientId();
replaceBlock(selectedBlockClientId, imageBlock);
} else {
props.setAttributes({
content: res.data
});
}
setTimeout(() => {
const {
getSelectedBlockClientId
} = wp.data.select("core/block-editor");
const block = document.querySelector(`[data-block="${getSelectedBlockClientId()}"]`);
if (block) {
const range = document.createRange();
const sel = window.getSelection();
range.setStart(block, 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}, 50);
} catch (e) {
console.error("Error:", e.message);
dispatch('core/notices').createErrorNotice(`AI Copilot error: ${e.message}`, {
isDismissible: true
});
} finally {
setBusy(false);
setDisplay(false);
setQuery('');
}
};
const onAiTextKeyDown = async e => {
if (composing) return;
if (e.key === 'Enter') {
e.preventDefault();
e.stopPropagation();
await executeQuery(query);
} else if (e.key === 'Escape' || e.key === 'Backspace' && !query) {
e.preventDefault();
setDisplay(false);
setQuery('');
}
};
useEffect(() => {
if (display && aiTextControlRef.current) {
aiTextControlRef.current.focus();
}
}, [display]);
useEffect(() => {
const handleEnterKey = event => {
if (display && event.key === 'Enter') {
event.preventDefault();
return false;
}
};
dispatch('core/keyboard-shortcuts').registerShortcut({
name: SHORTCUT_NAME,
category: 'block',
description: 'Prevent new block creation when AI Copilot is active',
keyCombination: {
character: 'enter'
}
});
window.addEventListener('keydown', handleEnterKey, true);
return () => {
window.removeEventListener('keydown', handleEnterKey, true);
dispatch('core/keyboard-shortcuts').unregisterShortcut(SHORTCUT_NAME);
};
}, [display]);
if (display) {
return /*#__PURE__*/React.createElement(Card, null, /*#__PURE__*/React.createElement(CardBody, null, !busy ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TextControl, {
ref: aiTextControlRef,
label: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_3__["default"], {
icon: "wand",
style: {
marginBottom: -4
}
}), "AI Copilot"),
value: query,
placeholder: isImageMode ? "Describe the image..." : "Write about...",
onChange: value => setQuery(value),
onKeyDown: onAiTextKeyDown,
onCompositionStart: () => setComposing(true),
onCompositionEnd: () => setComposing(false)
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'end',
marginBottom: -12
}
}, /*#__PURE__*/React.createElement(ToggleControl, {
label: "Image Mode",
checked: isImageMode,
onChange: setIsImageMode
}))) : /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'center',
padding: 20
}
}, /*#__PURE__*/React.createElement(ProgressBar, null))));
}
return /*#__PURE__*/React.createElement("div", {
onCompositionStart: () => setComposing(true),
onCompositionEnd: () => setComposing(false),
onKeyDown: handleKeyPress
}, /*#__PURE__*/React.createElement(props.BlockEdit, props));
};
const blockEditCopilot = BlockEdit => {
return props => {
if (props.name === 'core/paragraph') {
return /*#__PURE__*/React.createElement(EnhancedParagraphBlock, _extends({
BlockEdit: BlockEdit
}, props));
}
return /*#__PURE__*/React.createElement(BlockEdit, props);
};
};
addFilter("editor.BlockEdit", "mwai-copilot/module", blockEditCopilot);
const modifyPlaceholder = (settings, name) => {
if (name === "core/paragraph") {
const editFn = settings.edit;
settings.edit = props => {
props = {
...props,
attributes: {
...props.attributes,
placeholder: "Type / to choose a block, or press space to summon the AI Copilot"
}
};
return editFn(props);
};
}
return settings;
};
addFilter("blocks.registerBlockType", "mwai-copilot/placeholder", modifyPlaceholder);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BlockCopilot);
/***/ }),
/***/ "./app/js/modules/BlockFeatures.js":
/*!*****************************************!*\
!*** ./app/js/modules/BlockFeatures.js ***!
\*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _modals_GenerateTitles__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./modals/GenerateTitles */ "./app/js/modules/modals/GenerateTitles.js");
/* harmony import */ var _modals_GenerateExcerpts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./modals/GenerateExcerpts */ "./app/js/modules/modals/GenerateExcerpts.js");
/* harmony import */ var _styles_AiIcon__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../styles/AiIcon */ "./app/js/styles/AiIcon.js");
/* harmony import */ var _modals_MagicWandModal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modals/MagicWandModal */ "./app/js/modules/modals/MagicWandModal.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
const {
useState,
useEffect,
Fragment
} = wp.element;
const {
__
} = wp.i18n;
const {
registerPlugin
} = wp.plugins;
const {
Button,
ToolbarDropdownMenu,
ToolbarGroup,
Spinner,
MenuGroup,
MenuItem
} = wp.components;
const {
BlockControls
} = wp.blockEditor;
const {
PluginDocumentSettingPanel
} = wp.editor;
const {
addFilter
} = wp.hooks;
const {
createHigherOrderComponent
} = wp.compose;
//const { PluginBlockSettingsMenuItem } = wp.editPost;
const {
registerFormatType
} = wp.richText;
const {
useSelect
} = wp.data;
// NekoUI
// UI Engine
// SlotFills Reference
// https://developer.wordpress.org/block-editor/reference-guides/slotfills/
// Plugin Block Settings Menu Item Reference
// https://developer.wordpress.org/block-editor/reference-guides/slotfills/plugin-block-settings-menu-item/
function BlockAIWand() {
const [busy, setBusy] = useState(false);
const [results, setResults] = useState([]);
const [storedSelectedText, setStoredSelectedText] = useState('');
const selectedBlock = useSelect(select => select('core/block-editor').getSelectedBlock(), []);
if (!selectedBlock) {
return null;
}
// Block type check is now handled by the filter
const applyFadeOutStyle = element => {
element.style.opacity = 0.15;
element.style.pointerEvents = 'none';
element.style.userSelect = 'none';
element.style.animation = 'neko-fade-animation 0.85s infinite linear';
};
const applyNormalStyle = element => {
element.style.opacity = 1;
element.style.pointerEvents = 'auto';
element.style.userSelect = 'auto';
element.style.animation = 'none';
};
useEffect(() => {
if (!(selectedBlock !== null && selectedBlock !== void 0 && selectedBlock.clientId)) {
return;
}
// Try multiple methods to find the block element
let blockElement = document.getElementById('block-' + selectedBlock.clientId);
// If not found, try data attribute selector
if (!blockElement) {
blockElement = document.querySelector(`[data-block="${selectedBlock.clientId}"]`);
}
// If still not found, try WordPress block wrapper
if (!blockElement) {
blockElement = document.querySelector(`.wp-block[data-block="${selectedBlock.clientId}"]`);
}
if (!blockElement) {
console.warn("AI Engine: Could not find block element for", selectedBlock.name, selectedBlock.clientId);
return;
}
if (busy) {
applyFadeOutStyle(blockElement);
} else {
applyNormalStyle(blockElement);
}
}, [busy, selectedBlock]);
const setBlockStyle = () => {
// Try multiple methods to find the block element
let blockElement = document.getElementById('block-' + selectedBlock.clientId);
if (!blockElement) {
blockElement = document.querySelector(`[data-block="${selectedBlock.clientId}"]`);
}
if (!blockElement) {
blockElement = document.querySelector(`.wp-block[data-block="${selectedBlock.clientId}"]`);
}
if (!blockElement) {
console.warn("AI Engine: Could not find block element for", selectedBlock.name, selectedBlock.clientId);
return;
}
applyFadeOutStyle(blockElement);
};
const resetBlockStyle = () => {
// Try multiple methods to find the block element
let blockElement = document.getElementById('block-' + selectedBlock.clientId);
if (!blockElement) {
blockElement = document.querySelector(`[data-block="${selectedBlock.clientId}"]`);
}
if (!blockElement) {
blockElement = document.querySelector(`.wp-block[data-block="${selectedBlock.clientId}"]`);
}
if (!blockElement) {
console.warn("AI Engine: Could not find block element for", selectedBlock.name, selectedBlock.clientId);
return;
}
applyNormalStyle(blockElement);
};
const getBlockContent = (block, returnStructured = false) => {
switch (block.name) {
case 'core/list':
// Modern lists use innerBlocks for list items
if (block.innerBlocks && block.innerBlocks.length > 0) {
if (returnStructured) {
const items = block.innerBlocks.filter(innerBlock => innerBlock.name === 'core/list-item').map(innerBlock => {
// Try to get content from attributes first
if (innerBlock.attributes.content) {
return innerBlock.attributes.content;
}
// If content is not in attributes, try to extract from originalContent
if (innerBlock.originalContent) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = innerBlock.originalContent;
const liElement = tempDiv.querySelector('li');
return liElement ? liElement.textContent || liElement.innerText || '' : '';
}
return '';
});
return {
type: 'list',
items: items
};
}
// For text mode, join all list items
return block.innerBlocks.filter(innerBlock => innerBlock.name === 'core/list-item').map(innerBlock => {
if (innerBlock.attributes.content) {
return innerBlock.attributes.content;
}
if (innerBlock.originalContent) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = innerBlock.originalContent;
const liElement = tempDiv.querySelector('li');
return liElement ? liElement.textContent || liElement.innerText || '' : '';
}
return '';
}).join('\n');
}
// Fallback for legacy lists that use values attribute
if (returnStructured) {
const listHtml = block.attributes.values || '';
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listHtml;
const items = Array.from(tempDiv.querySelectorAll('li')).map(li => li.textContent || li.innerText || '');
return {
type: 'list',
items: items
};
}
const listHtml = block.attributes.values || '';
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listHtml;
return tempDiv.textContent || tempDiv.innerText || '';
case 'core/list-item':
// List items can have RichText or plain string content
const listItemContent = block.attributes.content;
// Handle RichText format
if (listItemContent && typeof listItemContent === 'object' && listItemContent.originalHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listItemContent.originalHTML;
return tempDiv.textContent || tempDiv.innerText || '';
}
// Handle plain string
if (typeof listItemContent === 'string') {
return listItemContent;
}
return '';
case 'core/quote':
return block.attributes.value || '';
case 'core/table':
const tableData = block.attributes.body || [];
// Helper function to extract text from cell content
const getCellText = cellContent => {
// Handle RichText format
if (cellContent && typeof cellContent === 'object' && cellContent.originalHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = cellContent.originalHTML;
return tempDiv.textContent || tempDiv.innerText || '';
}
// Handle plain string
if (typeof cellContent === 'string') {
return cellContent;
}
return '';
};
if (returnStructured) {
// Return structured data for tables
return {
type: 'table',
rows: tableData.map(row => ({
cells: row.cells ? row.cells.map(cell => getCellText(cell.content)) : []
}))
};
}
// For text mode, extract all text
let tableText = '';
tableData.forEach(row => {
if (row && row.cells) {
row.cells.forEach(cell => {
const text = getCellText(cell.content);
if (text) {
tableText += text + ' ';
}
});
tableText += '\n';
}
});
return tableText.trim();
case 'core/paragraph':
case 'core/heading':
default:
const content = block.attributes.content;
// Handle RichText format
if (content && typeof content === 'object' && content.originalHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = content.originalHTML;
return tempDiv.textContent || tempDiv.innerText || '';
}
// Handle plain string
return content || '';
}
};
const updateBlockContent = (block, newContent, isStructured = false) => {
let updateAttrs = {};
switch (block.name) {
case 'core/list':
if (isStructured && typeof newContent === 'object' && newContent.items) {
// Handle structured list data
const listHtml = newContent.items.map(item => `<li>${item}</li>`).join('');
updateAttrs = {
values: listHtml
};
} else {
// Handle plain text
const listItems = newContent.split('\n').filter(item => item.trim());
const listHtml = listItems.map(item => `<li>${item.trim()}</li>`).join('');
updateAttrs = {
values: listHtml
};
}
break;
case 'core/list-item':
// For list items, we need to preserve the RichText format if it was originally RichText
const originalContent = block.attributes.content;
if (originalContent && typeof originalContent === 'object' && originalContent.originalHTML !== undefined) {
// Create a new RichText object
// Note: This is a simplified approach - in production, you'd want to preserve formatting
updateAttrs = {
content: {
originalHTML: newContent
// Preserve other RichText properties if needed
}
};
} else {
// Plain string content
updateAttrs = {
content: newContent
};
}
break;
case 'core/quote':
updateAttrs = {
value: newContent
};
break;
case 'core/table':
if (isStructured && typeof newContent === 'object' && newContent.rows) {
// Handle structured table data
const originalBody = block.attributes.body || [];
// Build the new table body
const body = newContent.rows.map((row, rowIndex) => {
const originalRow = originalBody[rowIndex] || {
cells: []
};
return {
cells: row.cells.map((cellText, cellIndex) => {
var _originalRow$cells;
const originalCell = (_originalRow$cells = originalRow.cells) === null || _originalRow$cells === void 0 ? void 0 : _originalRow$cells[cellIndex];
const originalContent = originalCell === null || originalCell === void 0 ? void 0 : originalCell.content;
// For table cells, let's just pass the text and let WordPress handle RichText conversion
// WordPress should automatically convert strings to RichText when needed
return {
...originalCell,
content: cellText
};
})
};
});
updateAttrs = {
body
};
} else {
console.warn('AI Wand: Table requires structured data for proper update');
}
break;
case 'core/paragraph':
case 'core/heading':
default:
updateAttrs = {
content: newContent
};
break;
}
wp.data.dispatch('core/block-editor').updateBlockAttributes(block.clientId, updateAttrs);
};
const replaceText = newText => {
const selectedBlock = wp.data.select('core/block-editor').getSelectedBlock();
const blockContent = getBlockContent(selectedBlock);
// Use stored selected text if available (for suggest mode)
const textToReplace = storedSelectedText || window.getSelection().toString();
if (textToReplace && blockContent.includes(textToReplace)) {
// Simple text replacement
const updatedContent = blockContent.replace(textToReplace, newText);
updateBlockContent(selectedBlock, updatedContent);
setStoredSelectedText(''); // Clear stored text after use
} else {
// If we can't find the selection, just replace the whole block
console.warn('AI Wand: Could not find selection, replacing entire block content');
updateBlockContent(selectedBlock, newText);
}
};
const updateText = text => {
updateBlockContent(selectedBlock, text, false);
};
const onClick = text => {
setResults([]);
if (!text) {
setStoredSelectedText(''); // Clear stored text when closing
return;
}
// Trim the synonym to remove any trailing spaces
replaceText(text.trim());
};
const doAction = async action => {
const {
getSelectedBlockClientId,
getBlockIndex,
getCurrentPost
} = wp.data.select("core/editor");
const selectedBlockClientId = getSelectedBlockClientId();
const blockIndex = getBlockIndex(selectedBlockClientId);
const {
id: postId
} = getCurrentPost();
setBusy(true);
setBlockStyle();
document.activeElement.blur();
// Get block content and selected text at the time of action
const isComplexBlock = selectedBlock ? ['core/list', 'core/table'].includes(selectedBlock.name) : false;
const blockContent = selectedBlock ? getBlockContent(selectedBlock, isComplexBlock) : '';
const text = isComplexBlock && typeof blockContent === 'object' ? '' : blockContent;
const selectedText = window.getSelection().toString();
// Store selected text for suggest mode
if (action === 'suggestSynonyms' && selectedText) {
setStoredSelectedText(selectedText);
}
// Prepare the data payload
const dataPayload = {
postId
};
if (isComplexBlock) {
dataPayload.json = blockContent;
dataPayload.blockType = selectedBlock.name;
} else {
dataPayload.text = text;
dataPayload.selectedText = selectedText;
}
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/magic_wand`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
action,
data: dataPayload
}
});
resetBlockStyle();
setBusy(false);
const {
mode,
result,
results,
type
} = res.data;
if (mode === 'replace') {
if (type === 'json' && isComplexBlock) {
// Validate that we got proper JSON back
if (typeof result === 'object' && result !== null) {
updateBlockContent(selectedBlock, result, true);
} else {
console.error('AI Wand: Expected JSON object but got:', typeof result);
alert('Error: Invalid response format from AI');
}
} else if (type === 'text' || !isComplexBlock) {
updateText(result);
} else {
console.error('AI Wand: Unexpected response type:', type);
alert('Error: Unexpected response type');
}
} else if (mode === 'suggest') {
setResults(results);
} else if (mode === 'insertMedia') {
const {
media
} = res.data;
const {
createBlock
} = wp.blocks;
const block = createBlock('core/image', {
id: media.id,
url: media.url,
title: media.title,
caption: media.caption,
alt: media.alt
});
wp.data.dispatch('core/block-editor').insertBlock(block, blockIndex + 1);
}
} catch (err) {
resetBlockStyle();
setBusy(false);
// Check if it's an API error with a message
let errorMessage = 'An error occurred';
if (err.response && err.response.data && err.response.data.message) {
errorMessage = err.response.data.message;
} else if (err.message) {
errorMessage = err.message;
}
alert("AI Wand Error: " + errorMessage);
console.error("AI Wand Error:", err);
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
@keyframes neko-fade-animation {
0% { opacity: 0.15; }
50% { opacity: 0.3; }
100% { opacity: 0.15; }
}
`), /*#__PURE__*/React.createElement(BlockControls, null, /*#__PURE__*/React.createElement(ToolbarGroup, null, /*#__PURE__*/React.createElement(ToolbarDropdownMenu, {
icon: busy ? /*#__PURE__*/React.createElement(Spinner, null) : /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_2__["default"], {
icon: "wand",
style: {
marginRight: 0
}
}),
label: __('AI Wand')
}, () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(MenuItem, {
onClick: () => doAction('correctText')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Correct Text"), /*#__PURE__*/React.createElement("small", null, "Grammar & Spelling"))), /*#__PURE__*/React.createElement(MenuItem, {
onClick: () => doAction('enhanceText')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Enhance Text"), /*#__PURE__*/React.createElement("small", null, "Readibility & Quality"))), /*#__PURE__*/React.createElement(MenuItem, {
onClick: () => doAction('longerText')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Longer Text"), /*#__PURE__*/React.createElement("small", null, "Readibility"))), /*#__PURE__*/React.createElement(MenuItem, {
onClick: () => doAction('shorterText')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Shorter Text"), /*#__PURE__*/React.createElement("small", null, "Readibility"))), /*#__PURE__*/React.createElement(MenuItem, {
onClick: () => doAction('translateText')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Translate Text"), /*#__PURE__*/React.createElement("small", null, "To Post Language")))), /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(MenuItem, {
disabled: !window.getSelection().toString(),
onClick: () => doAction('suggestSynonyms')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Suggest Synonyms"), /*#__PURE__*/React.createElement("small", null, "For Selected Words")))), /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(MenuItem, {
onClick: () => doAction('generateImage')
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("b", null, "Generate Image"), /*#__PURE__*/React.createElement("small", null, "For this Text")))))))), /*#__PURE__*/React.createElement(_modals_MagicWandModal__WEBPACK_IMPORTED_MODULE_3__["default"], {
isOpen: results === null || results === void 0 ? void 0 : results.length,
results: results,
onClick: onClick,
onClose: () => setResults([])
}));
}
// AI Engine: Translate Post
const translateText = async (text, context) => {
if (!text) {
return text;
}
const {
getCurrentPost
} = wp.data.select("core/editor");
const {
id: postId
} = getCurrentPost();
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/magic_wand`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
action: 'translateSection',
data: {
postId: postId,
context,
text
}
}
});
const translation = res.data.result;
return translation;
//return text.split(' ').map(word => word.split('').reverse().join('')).join(' ');
};
const translatePost = async () => {
const {
getBlocks,
getBlockAttributes
} = wp.data.select("core/block-editor");
const {
updateBlockAttributes
} = wp.data.dispatch("core/block-editor");
const {
editPost,
savePost
} = wp.data.dispatch("core/editor");
const {
createInfoNotice,
removeNotice
} = wp.data.dispatch("core/notices");
const {
getEditedPostAttribute
} = wp.data.select("core/editor");
const noticeId = 'mwai-translation-progress-notice';
const blocks = getBlocks();
const originalTitle = getEditedPostAttribute('title');
const wholeContent = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.getPostContent)();
const updateProgressNotice = async progress => {
createInfoNotice(`Translating content... ${progress}%`, {
id: noticeId,
isDismissible: false
});
await new Promise(resolve => setTimeout(resolve, 100));
};
const applyFadeOutStyle = element => {
element.style.opacity = 0.15;
element.style.pointerEvents = 'none';
element.style.userSelect = 'none';
element.style.animation = 'neko-fade-animation 0.85s infinite linear';
};
const applyNormalStyle = element => {
element.style.opacity = 1;
element.style.pointerEvents = 'auto';
element.style.userSelect = 'auto';
element.style.animation = 'none';
};
// Apply fade-out effect to all blocks and the title
blocks.forEach(block => {
const blockElement = document.querySelector(`[data-block="${block.clientId}"]`);
if (blockElement) applyFadeOutStyle(blockElement);
});
const titleElement = document.querySelector('.editor-post-title__input');
if (titleElement) applyFadeOutStyle(titleElement);
await updateProgressNotice(0);
const totalItems = blocks.length + 2; // +2 for title and excerpt
let translatedItems = 0;
let translatedTitle = '';
try {
// Translate the title
translatedTitle = await translateText(originalTitle, wholeContent);
translatedItems++;
editPost({
title: translatedTitle
});
if (titleElement) applyNormalStyle(titleElement);
await updateProgressNotice(Math.round(translatedItems / totalItems * 100));
// Translate blocks
for (const block of blocks) {
if (['core/paragraph', 'core/heading', 'core/list', 'core/list-item', 'core/quote', 'core/table'].includes(block.name)) {
let content;
let updateAttrs = {};
// Extract content based on block type
switch (block.name) {
case 'core/list':
content = getBlockAttributes(block.clientId).values;
break;
case 'core/list-item':
content = getBlockAttributes(block.clientId).content;
break;
case 'core/quote':
content = getBlockAttributes(block.clientId).value;
break;
default:
content = getBlockAttributes(block.clientId).content;
break;
}
if (content) {
const translatedContent = await translateText(content, wholeContent);
// Update attributes based on block type
switch (block.name) {
case 'core/list':
updateAttrs = {
values: translatedContent
};
break;
case 'core/list-item':
updateAttrs = {
content: translatedContent
};
break;
case 'core/quote':
updateAttrs = {
value: translatedContent
};
break;
default:
updateAttrs = {
content: translatedContent
};
break;
}
await updateBlockAttributes(block.clientId, updateAttrs);
}
// Restore normal style to all blocks and the title
const blockElement = document.querySelector(`[data-block="${block.clientId}"]`);
if (blockElement) {
applyNormalStyle(blockElement);
}
// Focus on the block
wp.data.dispatch('core/block-editor').selectBlock(block.clientId);
}
translatedItems++;
await updateProgressNotice(Math.round(translatedItems / totalItems * 100));
}
// Translate the excerpt
const excerpt = getEditedPostAttribute('excerpt');
if (excerpt) {
const translatedExcerpt = await translateText(excerpt, wholeContent);
editPost({
excerpt: translatedExcerpt
});
}
} finally {
// Restore normal style to all blocks and the title
blocks.forEach(block => {
const blockElement = document.querySelector(`[data-block="${block.clientId}"]`);
if (blockElement) applyNormalStyle(blockElement);
});
removeNotice(noticeId);
}
};
// Paragraph Block: Menu
// const doOnClick = () => {
// alert("Coming soon! Let me know your feedback and ideas, I will make this awesome for you.");
// };
// const MWAI_Block_AI_Actions = () => (
// <>
// <PluginBlockSettingsMenuItem
// allowedBlocks={['core/paragraph']}
// icon={<AiIcon icon="wand" style={{ marginRight: 0 }} />}
// label={<> {__('Enhance text')}</>}
// onClick={doOnClick}
// />
// <PluginBlockSettingsMenuItem
// allowedBlocks={['core/paragraph']}
// icon={<AiIcon icon="wand" style={{ marginRight: 0 }} />}
// label={<> {__('Translate text')}</>}
// onClick={doOnClick}
// />
// </>
// );
// Document Settings: Panel
const MWAI_DocumentSettings = () => {
const suggestionsEnabled = _app_settings__WEBPACK_IMPORTED_MODULE_1__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_1__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_1__.options.module_suggestions;
const [postForTitle, setPostForTitle] = useState();
const [postForExcerpt, setPostForExcerpt] = useState();
const onTranslatePost = async () => {
await translatePost();
};
const onTitlesModalOpen = () => {
const {
getCurrentPost
} = wp.data.select("core/editor");
const {
id,
title
} = getCurrentPost();
setPostForTitle({
postId: id,
postTitle: title
});
};
const onExcerptsModalOpen = () => {
const {
getCurrentPost
} = wp.data.select("core/editor");
const {
id,
title
} = getCurrentPost();
setPostForExcerpt({
postId: id,
postTitle: title
});
};
const onTitleClick = async title => {
wp.data.dispatch('core/editor').editPost({
title
});
};
const onExcerptClick = async excerpt => {
wp.data.dispatch('core/editor').editPost({
excerpt
});
};
if (!suggestionsEnabled) {
return null;
}
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__["default"], null, /*#__PURE__*/React.createElement(PluginDocumentSettingPanel, {
name: "mwai-document-settings",
title: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_2__["default"], null), " AI Engine"),
className: "mwai-document-settings"
}, /*#__PURE__*/React.createElement("p", null, "Suggest:"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(Button, {
variant: "primary",
onClick: onTitlesModalOpen,
style: {
flex: 1,
marginRight: 10,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_2__["default"], {
icon: "wand",
style: {
marginRight: 8
}
}), " Titles"), /*#__PURE__*/React.createElement(Button, {
variant: "primary",
onClick: onExcerptsModalOpen,
style: {
flex: 1,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_2__["default"], {
icon: "wand",
style: {
marginRight: 8
}
}), " Excerpts")), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(Button, {
variant: "primary",
onClick: onTranslatePost,
style: {
flex: 1,
marginTop: 10,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement(_styles_AiIcon__WEBPACK_IMPORTED_MODULE_2__["default"], {
icon: "wand",
style: {
marginRight: 8
}
}), " Translate Post")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__["default"], null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoWrapper, null, /*#__PURE__*/React.createElement(_modals_GenerateTitles__WEBPACK_IMPORTED_MODULE_7__["default"], {
post: postForTitle,
onTitleClick: onTitleClick,
onClose: setPostForTitle
}), /*#__PURE__*/React.createElement(_modals_GenerateExcerpts__WEBPACK_IMPORTED_MODULE_8__["default"], {
post: postForExcerpt,
onExcerptClick: onExcerptClick,
onClose: setPostForExcerpt
})))));
};
const BlockFeatures = () => {
// This goes into the sidebar
registerPlugin('ai-engine-document-settings', {
render: MWAI_DocumentSettings
});
// This goes in the context menu of the block toolbar
// registerPlugin('ai-engine-ai-wand', {
// render: MWAI_Block_AI_Actions
// });
// This goes in the block toolbar directly
// Using block filter for better compatibility with all block types
const AIWandWrapper = ({
selectedBlock
}) => {
if (!selectedBlock) return null;
return /*#__PURE__*/React.createElement(BlockAIWand, null);
};
const withAIWand = createHigherOrderComponent(BlockEdit => {
return props => {
const supportedBlocks = ['core/paragraph', 'core/heading', 'core/list', 'core/list-item', 'core/quote', 'core/table'];
if (!supportedBlocks.includes(props.name)) {
return /*#__PURE__*/React.createElement(BlockEdit, props);
}
// Get selected block inside the component to avoid hooks issues
const SelectedBlockAIWand = () => {
const selectedBlock = useSelect(select => select('core/block-editor').getSelectedBlock(), []);
// Only render if this block is selected
if (!selectedBlock || selectedBlock.clientId !== props.clientId) {
return null;
}
return /*#__PURE__*/React.createElement(BlockAIWand, null);
};
return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(BlockEdit, props), /*#__PURE__*/React.createElement(SelectedBlockAIWand, null));
};
}, 'withAIWand');
addFilter('editor.BlockEdit', 'ai-engine/ai-wand', withAIWand);
};
// Debug utility for testing AI Wand in browser console
if (typeof window !== 'undefined') {
window.mwaiWand = {
getAllBlocks: () => {
const blocks = wp.data.select('core/block-editor').getBlocks();
const supportedBlocks = ['core/paragraph', 'core/heading', 'core/list', 'core/list-item', 'core/quote', 'core/table'];
const processBlock = (block, depth = 0) => {
const indent = ' '.repeat(depth);
const isSupported = supportedBlocks.includes(block.name);
const isComplex = ['core/list', 'core/table'].includes(block.name);
// Create a temporary function to get content
const getContent = (block, returnStructured = false) => {
switch (block.name) {
case 'core/list':
// Modern lists use innerBlocks for list items
if (block.innerBlocks && block.innerBlocks.length > 0) {
if (returnStructured) {
const items = block.innerBlocks.filter(innerBlock => innerBlock.name === 'core/list-item').map(innerBlock => innerBlock.attributes.content || '');
return {
type: 'list',
items: items
};
}
// For text mode, join all list items
return block.innerBlocks.filter(innerBlock => innerBlock.name === 'core/list-item').map(innerBlock => innerBlock.attributes.content || '').join('\n');
}
// Fallback for legacy lists that use values attribute
if (returnStructured) {
const listHtml = block.attributes.values || '';
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listHtml;
const items = Array.from(tempDiv.querySelectorAll('li')).map(li => li.textContent || li.innerText || '');
return {
type: 'list',
items: items
};
}
const listHtml = block.attributes.values || '';
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listHtml;
return tempDiv.textContent || tempDiv.innerText || '';
case 'core/list-item':
return block.attributes.content || '';
case 'core/quote':
return block.attributes.value || '';
case 'core/table':
if (returnStructured) {
const tableData = block.attributes.body || [];
return {
type: 'table',
rows: tableData.map(row => ({
cells: row.cells ? row.cells.map(cell => cell.content || '') : []
}))
};
}
const tableData = block.attributes.body || [];
let tableText = '';
tableData.forEach(row => {
if (row && row.cells) {
row.cells.forEach(cell => {
if (cell && cell.content) {
tableText += cell.content + ' ';
}
});
tableText += '\n';
}
});
return tableText.trim();
case 'core/paragraph':
case 'core/heading':
default:
return block.attributes.content || '';
}
};
console.log(`${indent}Block: ${block.name} (ID: ${block.clientId})`);
console.log(`${indent} Supported: ${isSupported}`);
console.log(`${indent} Attributes:`, block.attributes);
if (isSupported) {
const content = getContent(block, isComplex);
console.log(`${indent} Content (${isComplex ? 'JSON' : 'text'}):`, content);
console.log(`${indent} Payload to API:`, isComplex ? {
json: content,
blockType: block.name
} : {
text: content
});
}
// Process inner blocks
if (block.innerBlocks && block.innerBlocks.length > 0) {
console.log(`${indent} Inner blocks:`);
block.innerBlocks.forEach(innerBlock => processBlock(innerBlock, depth + 1));
}
};
console.log('=== AI Wand Block Analysis ===');
console.log('Supported block types:', supportedBlocks);
console.log('\nAll blocks in editor:');
blocks.forEach(block => processBlock(block));
console.log('\n=== End of Analysis ===');
return blocks;
},
getSelectedBlock: () => {
const block = wp.data.select('core/block-editor').getSelectedBlock();
if (!block) {
console.log('No block selected');
return null;
}
console.log('Selected block:', block.name);
console.log('Block ID:', block.clientId);
console.log('Attributes:', block.attributes);
console.log('Inner blocks:', block.innerBlocks);
console.log('Original content:', block.originalContent);
// Use the same logic as AI Wand
const isComplexBlock = ['core/list', 'core/table'].includes(block.name);
const blockContent = window.mwaiWand.getBlockContent(block, isComplexBlock);
const text = typeof blockContent === 'object' ? '' : blockContent;
console.log('Content extracted:', blockContent);
console.log('Text for API:', text);
console.log('Is complex block:', isComplexBlock);
if (isComplexBlock) {
console.log('Payload to API:', {
json: blockContent,
blockType: block.name
});
} else {
console.log('Payload to API:', {
text: text
});
}
return block;
},
getBlockContent: (block, returnStructured = false) => {
// Same logic as getBlockContent in the component
switch (block.name) {
case 'core/list':
// Modern lists use innerBlocks for list items
if (block.innerBlocks && block.innerBlocks.length > 0) {
if (returnStructured) {
const items = block.innerBlocks.filter(innerBlock => innerBlock.name === 'core/list-item').map(innerBlock => {
// Try to get content from attributes first
const content = innerBlock.attributes.content;
// Handle RichText format (object with originalHTML property)
if (content && typeof content === 'object' && content.originalHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = content.originalHTML;
return tempDiv.textContent || tempDiv.innerText || '';
}
// Handle plain string content
if (typeof content === 'string') {
return content;
}
// Fallback: try to extract from originalContent
if (innerBlock.originalContent) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = innerBlock.originalContent;
const liElement = tempDiv.querySelector('li');
return liElement ? liElement.textContent || liElement.innerText || '' : '';
}
return '';
});
return {
type: 'list',
items: items
};
}
// For text mode, join all list items
return block.innerBlocks.filter(innerBlock => innerBlock.name === 'core/list-item').map(innerBlock => {
const content = innerBlock.attributes.content;
// Handle RichText format (object with originalHTML property)
if (content && typeof content === 'object' && content.originalHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = content.originalHTML;
return tempDiv.textContent || tempDiv.innerText || '';
}
// Handle plain string content
if (typeof content === 'string') {
return content;
}
// Fallback: try to extract from originalContent
if (innerBlock.originalContent) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = innerBlock.originalContent;
const liElement = tempDiv.querySelector('li');
return liElement ? liElement.textContent || liElement.innerText || '' : '';
}
return '';
}).join('\n');
}
// Fallback for legacy lists that use values attribute
if (returnStructured) {
const listHtml = block.attributes.values || '';
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listHtml;
const items = Array.from(tempDiv.querySelectorAll('li')).map(li => li.textContent || li.innerText || '');
return {
type: 'list',
items: items
};
}
const listHtml = block.attributes.values || '';
const tempDiv = document.createElement('div');
tempDiv.innerHTML = listHtml;
return tempDiv.textContent || tempDiv.innerText || '';
case 'core/list-item':
return block.attributes.content || '';
case 'core/quote':
return block.attributes.value || '';
case 'core/table':
const tableData = block.attributes.body || [];
// Helper function to extract text from cell content
const getCellText = cellContent => {
// Handle RichText format
if (cellContent && typeof cellContent === 'object' && cellContent.originalHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = cellContent.originalHTML;
return tempDiv.textContent || tempDiv.innerText || '';
}
// Handle plain string
if (typeof cellContent === 'string') {
return cellContent;
}
return '';
};
if (returnStructured) {
return {
type: 'table',
rows: tableData.map(row => ({
cells: row.cells ? row.cells.map(cell => getCellText(cell.content)) : []
}))
};
}
// For text mode, extract all text
let tableText = '';
tableData.forEach(row => {
if (row && row.cells) {
row.cells.forEach(cell => {
const text = getCellText(cell.content);
if (text) {
tableText += text + ' ';
}
});
tableText += '\n';
}
});
return tableText.trim();
case 'core/paragraph':
case 'core/heading':
default:
return block.attributes.content || '';
}
},
testAction: async (action = 'correctText') => {
const block = wp.data.select('core/block-editor').getSelectedBlock();
if (!block) {
console.error('No block selected');
return;
}
console.log('Testing action:', action, 'on block:', block.name);
const isComplexBlock = ['core/list', 'core/table'].includes(block.name);
const blockContent = window.mwaiWand.getBlockContent(block, isComplexBlock);
const text = typeof blockContent === 'object' ? '' : blockContent;
const dataPayload = {
postId: wp.data.select('core/editor').getCurrentPost().id
};
if (isComplexBlock) {
dataPayload.json = blockContent;
dataPayload.blockType = block.name;
} else {
dataPayload.text = text;
dataPayload.selectedText = window.getSelection().toString();
}
console.log('Payload:', {
action,
data: dataPayload
});
try {
const response = await fetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/magic_wand`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce
},
body: JSON.stringify({
action,
data: dataPayload
})
});
const result = await response.json();
console.log('Response:', result);
return result;
} catch (error) {
console.error('Error:', error);
}
},
debugListItems: () => {
const block = wp.data.select('core/block-editor').getSelectedBlock();
if (!block || block.name !== 'core/list') {
console.log('Please select a list block');
return;
}
console.log('=== List Block Debug ===');
console.log('List block attributes:', block.attributes);
console.log('Number of inner blocks:', block.innerBlocks.length);
block.innerBlocks.forEach((item, index) => {
console.log(`\nList item ${index + 1}:`);
console.log(' Name:', item.name);
console.log(' Attributes:', item.attributes);
console.log(' Original content:', item.originalContent);
// Try to extract text
const tempDiv = document.createElement('div');
tempDiv.innerHTML = item.originalContent;
const liElement = tempDiv.querySelector('li');
const extractedText = liElement ? liElement.textContent || liElement.innerText || '' : '';
console.log(' Extracted text:', extractedText);
});
},
help: () => {
console.log('=== AI Wand Debug Utility ===');
console.log('Available commands:');
console.log(' mwaiWand.getAllBlocks() - Show all blocks and their content');
console.log(' mwaiWand.getSelectedBlock() - Show currently selected block info');
console.log(' mwaiWand.debugListItems() - Debug list items in selected list');
console.log(' mwaiWand.getBlockContent(block, structured) - Get content from a block');
console.log(' mwaiWand.testAction(action) - Test an AI Wand action on selected block');
console.log('\nAvailable actions: correctText, enhanceText, longerText, shorterText, translateText, suggestSynonyms');
console.log('\nExample: mwaiWand.testAction("correctText")');
}
};
console.log('AI Wand Debug Utility loaded. Type mwaiWand.help() for usage.');
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BlockFeatures);
/***/ }),
/***/ "./app/js/modules/PostsListTools.js":
/*!******************************************!*\
!*** ./app/js/modules/PostsListTools.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _modals_GenerateTitles__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modals/GenerateTitles */ "./app/js/modules/modals/GenerateTitles.js");
/* harmony import */ var _modals_GenerateExcerpts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./modals/GenerateExcerpts */ "./app/js/modules/modals/GenerateExcerpts.js");
// React & Vendor Libs
const {
useState,
useEffect
} = wp.element;
// NekoUI
// AI Engine
const PostsListTools = () => {
const [post, setPost] = useState();
useEffect(() => {
document.querySelectorAll('.mwai-link-title').forEach(item => {
const postId = item.getAttribute('data-id');
const postTitle = item.getAttribute('data-title');
item.addEventListener('click', () => {
setPost({
postId,
postTitle,
mode: 'title'
});
}, false);
});
document.querySelectorAll('.mwai-link-excerpt').forEach(item => {
const postId = item.getAttribute('data-id');
const postTitle = item.getAttribute('data-title');
item.addEventListener('click', () => {
setPost({
postId,
postTitle,
mode: 'excerpt'
});
}, false);
});
}, []);
const onTitleClick = async title => {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/helpers/update_post_title`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
postId: post.postId,
title
}
});
if (!res.success) {
throw new Error(res.message);
} else {
setPost();
// Look for the element tr[id="post-123"] and update the title
const tr = document.querySelector(`tr[id="post-${post.postId}"]`);
if (tr) {
const rowTitle = tr.querySelector('.row-title');
if (rowTitle) {
rowTitle.innerHTML = title;
}
}
// Also update the element .hidden .post_title
const hiddenTitle = tr.querySelector(`.hidden .post_title`);
if (hiddenTitle) {
hiddenTitle.innerHTML = title;
}
}
};
const onExcerptClick = async excerpt => {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/helpers/update_post_excerpt`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
postId: post.postId,
excerpt
}
});
if (!res.success) {
throw new Error(res.message);
} else {
setPost();
}
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__["default"], null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoWrapper, null, /*#__PURE__*/React.createElement(_modals_GenerateTitles__WEBPACK_IMPORTED_MODULE_4__["default"], {
post: (post === null || post === void 0 ? void 0 : post.mode) === 'title' ? post : null,
onTitleClick: onTitleClick,
onClose: () => {
setPost();
}
}), /*#__PURE__*/React.createElement(_modals_GenerateExcerpts__WEBPACK_IMPORTED_MODULE_5__["default"], {
post: (post === null || post === void 0 ? void 0 : post.mode) === 'excerpt' ? post : null,
onExcerptClick: onExcerptClick,
onClose: () => {
setPost();
}
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PostsListTools);
/***/ }),
/***/ "./app/js/modules/modals/GenerateExcerpts.js":
/*!***************************************************!*\
!*** ./app/js/modules/modals/GenerateExcerpts.js ***!
\***************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Spinner.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _styles_ModalStyles__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../styles/ModalStyles */ "./app/js/styles/ModalStyles.js");
// React & Vendor Libs
const {
useState,
useEffect,
useMemo
} = wp.element;
// NekoUI
// AI Engine
const GenerateExcerptsModal = props => {
const {
post,
onExcerptClick = {},
onClose = {}
} = props;
const [excerpts, setExcerpts] = useState([]);
const [busy, setBusy] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
if (post) {
fetchExcerpts(post);
}
}, [post]);
const fetchExcerpts = async ({
postId
}) => {
setBusy(true);
try {
var _res$data;
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/magic_wand`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
action: 'suggestExcerpts',
data: {
postId
}
}
});
setExcerpts((_res$data = res.data) === null || _res$data === void 0 ? void 0 : _res$data.results);
} catch (err) {
console.error(err);
setError(err.message);
}
setBusy(false);
};
const onClick = async title => {
setBusy(true);
try {
await onExcerptClick(title);
cleanClose();
} catch (e) {
setError(e.message);
}
setBusy(false);
};
const cleanClose = async () => {
onClose();
setExcerpts([]);
setError();
setBusy(false);
};
const content = useMemo(() => {
if (busy) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpinner, {
type: "circle",
size: "10%"
});
} else if (error) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Error: ", error);
} else if ((excerpts === null || excerpts === void 0 ? void 0 : excerpts.length) > 0) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Pick a new excerpt by clicking on it.", /*#__PURE__*/React.createElement(_styles_ModalStyles__WEBPACK_IMPORTED_MODULE_3__.ResultsContainer, null, excerpts.map(x => /*#__PURE__*/React.createElement(_styles_ModalStyles__WEBPACK_IMPORTED_MODULE_3__.Result, {
key: x,
onClick: () => {
onClick(x);
}
}, x))));
} else {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Nothing to display.");
}
}, [busy, excerpts, error]);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoModal, {
isOpen: post,
onRequestClose: cleanClose,
title: `New excerpt for "${post === null || post === void 0 ? void 0 : post.postTitle}"`,
content: content,
okButton: {
label: "Close",
onClick: cleanClose
}
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GenerateExcerptsModal);
/***/ }),
/***/ "./app/js/modules/modals/GenerateTitles.js":
/*!*************************************************!*\
!*** ./app/js/modules/modals/GenerateTitles.js ***!
\*************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Spinner.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _styles_ModalStyles__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../styles/ModalStyles */ "./app/js/styles/ModalStyles.js");
// React & Vendor Libs
const {
useState,
useEffect,
useMemo
} = wp.element;
// NekoUI
// AI Engine
const GenerateTitlesModal = props => {
const {
post,
onTitleClick = {},
onClose = {}
} = props;
const [titles, setTitles] = useState([]);
const [busy, setBusy] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
if (post) {
fetchTitles(post);
}
}, [post]);
const fetchTitles = async ({
postId,
postTitle
}) => {
setBusy(true);
try {
var _res$data;
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/magic_wand`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
action: 'suggestTitles',
data: {
postId
}
}
});
setTitles((_res$data = res.data) === null || _res$data === void 0 ? void 0 : _res$data.results);
} catch (err) {
console.error(err);
setError(err.message);
}
setBusy(false);
};
const onClick = async title => {
setBusy(true);
try {
await onTitleClick(title);
cleanClose();
} catch (e) {
setError(e.message);
}
setBusy(false);
};
const cleanClose = async () => {
onClose();
setTitles([]);
setError();
setBusy(false);
};
const content = useMemo(() => {
if (busy) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpinner, {
type: "circle",
size: "10%"
});
} else if (error) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Error: ", error);
} else if ((titles === null || titles === void 0 ? void 0 : titles.length) > 0) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Pick a new title by clicking on it.", /*#__PURE__*/React.createElement(_styles_ModalStyles__WEBPACK_IMPORTED_MODULE_3__.ResultsContainer, null, titles.map(x => /*#__PURE__*/React.createElement(_styles_ModalStyles__WEBPACK_IMPORTED_MODULE_3__.Result, {
key: x,
onClick: () => {
onClick(x);
}
}, x))));
} else {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Nothing to display.");
}
}, [busy, titles, error]);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoModal, {
isOpen: post,
onRequestClose: cleanClose,
title: `New title for "${post === null || post === void 0 ? void 0 : post.postTitle}"`,
content: content,
okButton: {
label: "Close",
onClick: cleanClose
}
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GenerateTitlesModal);
/***/ }),
/***/ "./app/js/modules/modals/MagicWandModal.js":
/*!*************************************************!*\
!*** ./app/js/modules/modals/MagicWandModal.js ***!
\*************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Spinner.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _styles_ModalStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../styles/ModalStyles */ "./app/js/styles/ModalStyles.js");
// React & Vendor Libs
const {
useState,
useEffect,
useMemo
} = wp.element;
// NekoUI
// AI Engine
const MagicWandModal = props => {
const {
isOpen = false,
title,
error,
results,
busy = false,
onClick = () => {}
} = props;
const createHash = str => {
let hash = 0;
if (str.length === 0) return hash;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash = hash & hash;
}
return hash;
};
const content = useMemo(() => {
if (busy) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_0__.NekoSpinner, {
type: "circle",
size: "10%"
});
} else if (error) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Error: ", error);
} else if ((results === null || results === void 0 ? void 0 : results.length) > 0) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Pick one of those results:", /*#__PURE__*/React.createElement(_styles_ModalStyles__WEBPACK_IMPORTED_MODULE_1__.ResultsContainer, null, results.map(x => /*#__PURE__*/React.createElement(_styles_ModalStyles__WEBPACK_IMPORTED_MODULE_1__.Result, {
key: createHash(x),
onClick: () => {
onClick(x);
}
}, x))));
} else {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Nothing to display.");
}
}, [results, error]);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__["default"], null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoModal, {
isOpen: isOpen,
title: title ?? "Results",
content: content,
onRequestClose: () => onClick(),
okButton: {
label: "Close",
onClick: () => onClick()
}
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MagicWandModal);
/***/ }),
/***/ "./app/js/requests.js":
/*!****************************!*\
!*** ./app/js/requests.js ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ clearLogs: () => (/* binding */ clearLogs),
/* harmony export */ deleteFiles: () => (/* binding */ deleteFiles),
/* harmony export */ refreshLogs: () => (/* binding */ refreshLogs),
/* harmony export */ retrieveAssistants: () => (/* binding */ retrieveAssistants),
/* harmony export */ retrieveChatbots: () => (/* binding */ retrieveChatbots),
/* harmony export */ retrieveDeletedFineTunes: () => (/* binding */ retrieveDeletedFineTunes),
/* harmony export */ retrieveEmbeddingsEnvironments: () => (/* binding */ retrieveEmbeddingsEnvironments),
/* harmony export */ retrieveFiles: () => (/* binding */ retrieveFiles),
/* harmony export */ retrieveFilesFromOpenAI: () => (/* binding */ retrieveFilesFromOpenAI),
/* harmony export */ retrieveFineTunes: () => (/* binding */ retrieveFineTunes),
/* harmony export */ retrieveModels: () => (/* binding */ retrieveModels),
/* harmony export */ retrieveOptions: () => (/* binding */ retrieveOptions),
/* harmony export */ retrievePostContent: () => (/* binding */ retrievePostContent),
/* harmony export */ retrievePostTypes: () => (/* binding */ retrievePostTypes),
/* harmony export */ retrievePostsCount: () => (/* binding */ retrievePostsCount),
/* harmony export */ retrieveThemes: () => (/* binding */ retrieveThemes),
/* harmony export */ setAssistantFunctions: () => (/* binding */ setAssistantFunctions),
/* harmony export */ updateChatbots: () => (/* binding */ updateChatbots),
/* harmony export */ updateThemes: () => (/* binding */ updateThemes)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
// NekoUI
// Wrapper for nekoFetch that handles token updates
const mwaiNekoFetch = async (url, options = {}) => {
// Always use the current nonce
const currentNonce = (0,_app_settings__WEBPACK_IMPORTED_MODULE_0__.getRestNonce)();
const updatedOptions = {
...options,
nonce: currentNonce
};
try {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(url, updatedOptions);
// Check for new token in response
if (response && response.new_token) {
// Log token update with expiration info
if (response.token_expires_at) {
const expiresAt = new Date(response.token_expires_at * 1000);
console.log(`[MWAI] 🔐 New token received - expires at ${expiresAt.toLocaleTimeString()} (in ${response.token_expires_in}s)`);
} else {
console.log('[MWAI] 🔐 New token received');
}
(0,_app_settings__WEBPACK_IMPORTED_MODULE_0__.updateRestNonce)(response.new_token);
}
return response;
} catch (error) {
// If error is due to invalid nonce, try to refresh and retry once
if (error.message && error.message.includes('nonce')) {
console.log('[MWAI] Nonce error detected, attempting to refresh...');
const refreshResponse = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/start_session`, {
method: 'POST'
});
if (refreshResponse && refreshResponse.restNonce) {
(0,_app_settings__WEBPACK_IMPORTED_MODULE_0__.updateRestNonce)(refreshResponse.restNonce);
// Retry with new nonce
return await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(url, {
...options,
nonce: refreshResponse.restNonce
});
}
}
throw error;
}
};
//#region Posts
const retrievePostTypes = async () => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/helpers/post_types`);
if (!res.success) {
throw new Error(res.message);
}
return res.postTypes;
};
const retrievePostsCount = async postType => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/helpers/count_posts?postType=${postType}`);
return res !== null && res !== void 0 && res.count ? parseInt(res === null || res === void 0 ? void 0 : res.count) : null;
};
const retrievePostContent = async (postType, offset = 0, postId = 0) => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/helpers/post_content?postType=${postType}&offset=${offset}&postId=${postId}`);
return res;
};
//#endregion
//#region Files
const deleteFiles = async files => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/mwai-ui/v1/files/delete`, {
method: 'POST',
json: {
files
}
});
if (!res.success) {
throw new Error(res.message);
}
return res;
};
const retrieveFilesFromOpenAI = async (envId = null, purpose = null) => {
var _res$files;
let url = `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/openai/files/list?envId=${envId}`;
if (purpose) {
url += `&purpose=${purpose}`;
}
const res = await mwaiNekoFetch(url);
if (!res.success) {
throw new Error(res.message);
}
return res === null || res === void 0 || (_res$files = res.files) === null || _res$files === void 0 ? void 0 : _res$files.data;
};
const retrieveFiles = async ({
userId = null,
purpose = null,
metadata = null,
envId = null,
limit = 10,
page = 0
}) => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/mwai-ui/v1/files/list`, {
method: 'POST',
json: {
userId,
purpose,
metadata,
envId,
limit,
page
}
});
if (!res.success) {
throw new Error(res.message);
}
return res === null || res === void 0 ? void 0 : res.data;
};
const retrieveDeletedFineTunes = async (envId = null, legacy = false) => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/openai/finetunes/list_deleted?envId=${envId}&legacy=${legacy}`);
if (!res.success) {
throw new Error(res.message);
}
return res === null || res === void 0 ? void 0 : res.finetunes;
};
//#endregion
//#region Themes
const retrieveThemes = async () => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/themes`, {
method: 'GET'
});
return res === null || res === void 0 ? void 0 : res.themes;
};
const updateThemes = async themes => {
// Make sure all the themeId of each theme in themes are unique. Let's loop through them, and if one is identical to any other before, let's add a number to it.
const themeIds = [];
for (let i = 0; i < themes.length; i++) {
let themeId = themes[i].themeId;
if (themeIds.includes(themeId)) {
let j = 1;
while (themeIds.includes(themeId + '-' + j)) {
j++;
}
themeId = themeId + '-' + j;
}
themeIds.push(themeId);
themes[i].themeId = themeId;
}
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/themes`, {
method: 'POST',
json: {
themes
}
});
return res === null || res === void 0 ? void 0 : res.themes;
};
//#endregion
//#region Chatbots
const retrieveModels = async () => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/openai/models`);
if (!res.success) {
throw new Error(res.message);
}
return res === null || res === void 0 ? void 0 : res.models;
};
const retrieveFineTunes = async (envId = null, legacy = false) => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/openai/finetunes/list?envId=${envId}&legacy=${legacy}`);
if (!res.success) {
throw new Error(res.message);
}
return res === null || res === void 0 ? void 0 : res.finetunes;
};
const retrieveChatbots = async () => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/chatbots`, {
method: 'GET'
});
if (!res.success) {
throw new Error(res === null || res === void 0 ? void 0 : res.message);
}
return res === null || res === void 0 ? void 0 : res.chatbots;
};
const updateChatbots = async chatbots => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/chatbots`, {
method: 'POST',
json: {
chatbots
}
});
if (!res.success) {
throw new Error(res === null || res === void 0 ? void 0 : res.message);
}
return res === null || res === void 0 ? void 0 : res.chatbots;
};
const retrieveAssistants = async envId => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/openai/assistants/list?envId=${envId}`);
if (!res.success) {
throw new Error(res.message);
}
return res === null || res === void 0 ? void 0 : res.assistants;
};
const setAssistantFunctions = async (envId, assistantId, functions) => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/openai/assistants/set_functions`, {
method: 'POST',
json: {
envId,
assistantId,
functions
}
});
if (!res.success) {
throw new Error(res.message);
}
return res;
};
//#endregion
//#region Options
const retrieveOptions = async () => {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/options`, {
method: 'GET'
});
return res === null || res === void 0 ? void 0 : res.options;
};
const retrieveEmbeddingsEnvironments = async () => {
const options = await retrieveOptions();
return (options === null || options === void 0 ? void 0 : options.embeddings_envs) || [];
};
//#endregion
//#region Logs
const refreshLogs = async () => {
try {
const res = await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/get_logs`, {
method: 'GET'
});
return res.data;
} catch (err) {
throw new Error(err.message);
}
};
const clearLogs = async () => {
try {
await mwaiNekoFetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/clear_logs`);
} catch (err) {
throw new Error(err.message);
}
};
//#endregion
/***/ }),
/***/ "./app/js/screens/Addons.js":
/*!**********************************!*\
!*** ./app/js/screens/Addons.js ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/toolbar/Toolbar.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Logo.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
// React & Vendor Libs
const {
useState,
useMemo
} = wp.element;
// NekoUI
const StyledAddonsContainer = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 20px;
`;
const Addons = ({
addons
}) => {
const initialFilter = addons.some(addon => addon.enabled) ? "enabled" : "all";
const [filter, setFilter] = useState(initialFilter);
const filteredAddons = useMemo(() => {
if (filter === "enabled") {
return addons.filter(addon => addon.enabled);
} else if (filter === "disabled") {
return addons.filter(addon => !addon.enabled);
}
return addons;
}, [addons, filter]);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoColumn, {
minimal: true,
fullWidth: true,
style: {
padding: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoToolbar, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoQuickLinks, {
name: "filter",
value: filter,
onChange: value => setFilter(value)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "All",
value: "all"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Enabled",
value: "enabled"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoLink, {
title: "Disabled",
value: "disabled"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, null), /*#__PURE__*/React.createElement(StyledAddonsContainer, null, filteredAddons.map(addon => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoContainer, {
key: addon.id,
style: {
marginBottom: 0
},
footer: /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
width: '100%',
alignItems: 'center',
marginLeft: 10,
minHeight: 30
}
}, /*#__PURE__*/React.createElement("span", {
style: {
fontSize: '11px',
marginRight: 15,
color: addon.enabled ? '#4CAF50' : '#666',
textTransform: 'uppercase',
fontWeight: 'bold'
}
}, addon.enabled ? /*#__PURE__*/React.createElement("label", null, "Enabled") : /*#__PURE__*/React.createElement("label", null, "Disabled")), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), addon.enabled && addon.settings_url && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
className: "primary",
onClick: () => window.open(addon.settings_url, '_self')
}, "Settings"), !addon.enabled && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
className: "primary",
onClick: () => window.open(addon.install_url, '_blank')
}, "Install"))
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
width: 32,
marginTop: -5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoLogo, null)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTypo, {
h3: true,
style: {
margin: 0,
marginLeft: 8,
fontWeight: 'bold'
}
}, addon.name), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 5,
marginTop: 3,
fontSize: 10,
color: '#fec74c'
}
},
// Based on addon.stars, display many ★}
Array.from({
length: addon.stars
}, (_, i) => /*#__PURE__*/React.createElement("span", {
key: i
}, "\u2605")))), /*#__PURE__*/React.createElement("div", {
className: "addon-description"
}, addon.description))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Addons);
/***/ }),
/***/ "./app/js/screens/ContentGenerator.js":
/*!********************************************!*\
!*** ./app/js/screens/ContentGenerator.js ***!
\********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/hooks.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Page.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_constants__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @app/constants */ "./app/js/constants.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @app/styles/CommonStyles */ "./app/js/styles/CommonStyles.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _app_components_Templates__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/components/Templates */ "./app/js/components/Templates.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _components_UsageCosts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/UsageCosts */ "./app/js/components/UsageCosts.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
// React & Vendor Libs
const {
useState,
useEffect,
useMemo,
useRef
} = wp.element;
// NekoUI
/**
* Returns a message with SEO recommendations based on the title.
*/
const getSeoMessage = title => {
if (!title) return null;
const words = title.split(' ');
const wordCount = words.length;
const charCount = title.length;
const seoMessage = [];
if (!charCount) {
return;
} else if (wordCount < 3) {
seoMessage.push(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_TOO_SHORT);
} else if (wordCount > 8) {
seoMessage.push(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_TOO_LONG);
} else if (charCount < 40) {
seoMessage.push(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_TOO_SHORT);
} else if (charCount > 70) {
seoMessage.push(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_TOO_LONG_2);
}
return seoMessage.join(' ');
};
const ContentGenerator = () => {
// Generated Content
const [content, setContent] = useState("");
const [excerpt, setExcerpt] = useState("");
// System
const {
template,
setTemplate,
clearTemplate,
jsxTemplates
} = (0,_app_components_Templates__WEBPACK_IMPORTED_MODULE_1__["default"])('contentGenerator');
const bulkTasks = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.useNekoTasks)();
const [busy, setBusy] = useState(false);
const [error, setError] = useState();
const [showModelParams, setShowModelParams] = useState(false);
const [showPostParams, setShowPostParams] = useState(false);
const [showPrompts, setShowPrompts] = useState(false);
const [showUsage, setShowUsage] = useState(false);
const [createdPostId, setCreatedPostId] = useState();
const [postType, setPostType] = useState('post');
const [topicsArray, setTopicsArray] = useState([]);
const [createdPosts, setCreatedPosts] = useState([]);
const [runTimes, setRunTimes] = useState({});
const abortController = useRef();
// Queries
const {
isLoading: isLoadingPostTypes,
data: postTypes
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_3__.useQuery)({
queryKey: ['postTypes'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_4__.retrievePostTypes
});
const isBusy = bulkTasks.busy || busy;
const onStop = () => {
var _abortController$curr;
(_abortController$curr = abortController.current) === null || _abortController$curr === void 0 || _abortController$curr.abort();
setBusy(false);
setRunTimes({});
};
// Template Properties
const title = (template === null || template === void 0 ? void 0 : template.title) ?? "";
const sections = (template === null || template === void 0 ? void 0 : template.sections) ?? "";
const mode = (template === null || template === void 0 ? void 0 : template.mode) ?? 'single';
const topic = (template === null || template === void 0 ? void 0 : template.topic) ?? "";
const topics = (template === null || template === void 0 ? void 0 : template.topics) ?? "";
const context = (template === null || template === void 0 ? void 0 : template.context) ?? "";
const model = (template === null || template === void 0 ? void 0 : template.model) ?? (_app_settings__WEBPACK_IMPORTED_MODULE_5__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_5__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_5__.options.ai_default_model) ?? null;
const sectionsCount = (template === null || template === void 0 ? void 0 : template.sectionsCount) ?? 2;
const paragraphsCount = (template === null || template === void 0 ? void 0 : template.paragraphsCount) ?? 3;
const writingStyle = (template === null || template === void 0 ? void 0 : template.writingStyle) ?? "creative";
const writingTone = (template === null || template === void 0 ? void 0 : template.writingTone) ?? "cheerful";
const titlePromptFormat = (template === null || template === void 0 ? void 0 : template.titlePromptFormat) ?? "";
const sectionsPromptFormat = (template === null || template === void 0 ? void 0 : template.sectionsPromptFormat) ?? "";
const contentPromptFormat = (template === null || template === void 0 ? void 0 : template.contentPromptFormat) ?? "";
const excerptPromptFormat = (template === null || template === void 0 ? void 0 : template.excerptPromptFormat) ?? "";
const envId = (template === null || template === void 0 ? void 0 : template.envId) ?? "";
const temperature = (template === null || template === void 0 ? void 0 : template.temperature) ?? 0.6;
const maxTokens = template === null || template === void 0 ? void 0 : template.maxTokens; // Remove the fallback
const topicsAreTitles = (template === null || template === void 0 ? void 0 : template.topicsAreTitles) ?? false;
const noSections = !sectionsPromptFormat || !sectionsCount;
const useMaxTokens = (template === null || template === void 0 ? void 0 : template.useMaxTokens) ?? false; // New property
// AI Environment
const {
completionModels,
calculatePrice
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.useModels)(_app_settings__WEBPACK_IMPORTED_MODULE_5__.options, envId || null);
const {
addUsage,
jsxUsageCosts
} = (0,_components_UsageCosts__WEBPACK_IMPORTED_MODULE_7__["default"])(calculatePrice);
const aiEnvironments = (_app_settings__WEBPACK_IMPORTED_MODULE_5__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_5__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_5__.options.ai_envs) || [];
const {
jsxLanguageSelector,
currentLanguage,
isCustom,
currentHumanLanguage
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.useLanguages)({
options: _app_settings__WEBPACK_IMPORTED_MODULE_5__.options,
language: template === null || template === void 0 ? void 0 : template.language,
customLanguage: template === null || template === void 0 ? void 0 : template.customLanguage
});
// SEO Advice
const titleMessage = useMemo(() => getSeoMessage(title), [title]);
/**
* Helper to set a template property.
*/
const setTemplateProperty = (value, property) => {
setTemplate(x => {
const newTemplate = {
...x,
[property]: value
};
// When envId is set to empty (Default), reset model to empty as well
if (property === 'envId' && value === '') {
newTemplate.model = '';
}
return newTemplate;
});
};
/**
* Keep topicsArray in sync with `template?.topics`.
*/
useEffect(() => {
const freshTopicsArray = topics.split('\n').map(x => x.trim()).filter(x => !!x);
setTopicsArray(freshTopicsArray);
}, [topics]);
/**
* Whenever title or sectionsCount change, clear the sections.
*/
useEffect(() => {
if (template) {
setTemplateProperty('', 'sections');
}
}, [title, sectionsCount]);
/**
* Whenever sections or paragraphsCount change, reset content and excerpt and post ID.
*/
useEffect(() => {
setContent('');
setExcerpt('');
setCreatedPostId();
}, [sections, paragraphsCount]);
/**
* Sync language selection with custom language states, if needed.
*/
useEffect(() => {
if (!template) return;
if (!isCustom && template.customLanguage) {
setTemplateProperty(null, 'customLanguage');
}
if (isCustom && template.customLanguage !== currentHumanLanguage) {
setTemplateProperty(currentHumanLanguage, 'customLanguage');
}
if (template.language !== currentLanguage) {
setTemplateProperty(currentLanguage, 'language');
}
}, [isCustom, currentLanguage, currentHumanLanguage]);
/**
* Replaces placeholders with actual values from the template.
*/
const finalizePrompt = (prompt, inContext = context) => {
// If there's context, include it; otherwise, remove the context section entirely
let contextReplacement = '';
if (inContext && inContext.trim()) {
contextReplacement = inContext;
} else {
// Remove the entire context section if no context is provided
prompt = prompt.replace(/### CONTEXT:[\s\S]*?(?=(###|Write|Create|Generate)|$)/g, '').trim();
prompt = prompt.replace(/### WRITING CONTEXT:[\s\S]*?(?=(###|Write|Create|Generate)|$)/g, '').trim();
}
return prompt.replace('{LANGUAGE}', currentHumanLanguage).replace('{WRITING_STYLE}', writingStyle).replace('{WRITING_TONE}', writingTone).replace('{PARAGRAPHS_PER_SECTION}', paragraphsCount).replace('{SECTIONS_COUNT}', sectionsCount).replace('{CONTEXT}', contextReplacement);
};
/**
* Return an object of booleans for placeholders usage in the prompts.
*/
const formInputs = useMemo(() => {
const lookFor = (str, arr) => !!arr.find(item => item.includes(str));
const arr = [titlePromptFormat, sectionsPromptFormat, contentPromptFormat, excerptPromptFormat];
return {
language: lookFor('{LANGUAGE}', arr),
writingStyle: lookFor('{WRITING_STYLE}', arr),
writingTone: lookFor('{WRITING_TONE}', arr),
sectionsCount: lookFor('{SECTIONS_COUNT}', arr),
paragraphsCount: lookFor('{PARAGRAPHS_PER_SECTION}', arr),
context: lookFor('{CONTEXT}', arr)
};
}, [titlePromptFormat, sectionsPromptFormat, contentPromptFormat, excerptPromptFormat, sectionsCount, paragraphsCount]);
/**
* This function calls the AI completions endpoint.
* If useMaxTokens is checked, we attach maxTokens to the request.
*/
const onSubmitPrompt = async (promptToUse, isBulk = false) => {
// Initialize abortController if not already initialized
if (!abortController.current) {
abortController.current = new AbortController();
}
try {
var _res$usage, _res$usage2;
const body = {
scope: 'admin-tools',
envId: envId || null,
model: model || null,
session: _app_settings__WEBPACK_IMPORTED_MODULE_5__.session,
message: promptToUse,
temperature
};
// TODO: Check if people complain about not having the Max Tokens settings.
// if (useMaxTokens && maxTokens) {
// body.maxTokens = maxTokens;
// }
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_5__.apiUrl}/ai/completions`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_5__.restNonce,
signal: abortController.current.signal,
json: body
});
addUsage(model, (res === null || res === void 0 || (_res$usage = res.usage) === null || _res$usage === void 0 ? void 0 : _res$usage.prompt_tokens) || 0, (res === null || res === void 0 || (_res$usage2 = res.usage) === null || _res$usage2 === void 0 ? void 0 : _res$usage2.completion_tokens) || 0);
let data = res.data.trim();
if (data.startsWith('"') && data.endsWith('"')) {
data = data.substring(1, data.length - 1);
}
return data;
} catch (err) {
if (isBulk) {
throw new Error(err.message);
}
if (err.name !== 'AbortError') {
console.error(err);
setError(err.message);
}
return null;
}
};
/**
* Generates sections based on the provided title/topic.
*/
const submitSectionsPrompt = async (inTopic = topic, inTitle = title, isBulk = false) => {
if (!inTitle) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_MISSING);
return;
}
setBusy(true);
setRunTimes({
...runTimes,
sections: new Date()
});
setTemplateProperty('', 'sections');
let prompt = sectionsPromptFormat.replace('{TITLE}', inTitle).replace('{TOPIC}', inTopic);
prompt = finalizePrompt(prompt);
let freshSections = await onSubmitPrompt(prompt, isBulk);
freshSections = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.cleanSections)(freshSections);
if (freshSections) {
setTemplateProperty(freshSections, 'sections');
}
setBusy(false);
setRunTimes({
...runTimes,
sections: null
});
return freshSections;
};
/**
* Generates content based on the provided title/sections.
*/
const submitContentPrompt = async (inTopic = topic, inTitle = title, inSections = sections, isBulk = false) => {
if (!inTitle) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_MISSING);
return;
}
if (!noSections && !inSections) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.SECTIONS_MISSING);
return;
}
setBusy(true);
setRunTimes({
...runTimes,
content: new Date()
});
setContent(() => "");
let prompt = contentPromptFormat.replace('{TITLE}', inTitle).replace('{SECTIONS}', inSections).replace('{TOPIC}', inTopic);
prompt = finalizePrompt(prompt);
let freshContent = await onSubmitPrompt(prompt, isBulk);
if (freshContent) {
// Clean up any placeholders that might remain
freshContent = freshContent.replace(/^===INTRO:\n/, '').replace(/^===INTRO: \n/, '').replace(/===INTRO: /, '').replace(/===OUTRO:\n/, '').replace(/===OUTRO: \n/, '').replace(/===OUTRO: /, '');
setContent(() => freshContent);
}
setBusy(false);
setRunTimes({
...runTimes,
content: null
});
return freshContent;
};
/**
* Generates an excerpt based on the provided title/topic.
*/
const onSubmitPromptForExcerpt = async (inTopic = topic, inTitle = title, isBulk = false) => {
if (!inTitle) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TITLE_MISSING);
return;
}
setBusy(true);
setRunTimes({
...runTimes,
excerpt: new Date()
});
setExcerpt(() => "");
let prompt = excerptPromptFormat.replace('{TITLE}', inTitle).replace('{TOPIC}', inTopic);
prompt = finalizePrompt(prompt);
const freshExcerpt = await onSubmitPrompt(prompt, isBulk);
if (freshExcerpt) {
setExcerpt(() => freshExcerpt);
}
setBusy(false);
setRunTimes({
...runTimes,
excerpt: null
});
return freshExcerpt;
};
/**
* Generates title, sections, content, and excerpt in one go.
*/
const onGenerateAllClick = async (inTopic = topic, isBulk = false) => {
setBusy(true);
abortController.current = new AbortController();
setRunTimes({
...runTimes,
all: new Date()
});
try {
// Title
let freshTitle = inTopic;
if (!topicsAreTitles || !isBulk) {
const prompt = finalizePrompt(titlePromptFormat.replace('{TOPIC}', inTopic));
freshTitle = await onSubmitPrompt(prompt, isBulk);
}
let freshSections = null;
let freshContent = null;
let freshExcerpt = null;
setBusy(false);
if (freshTitle) {
setTemplateProperty(freshTitle, 'title');
if (!noSections) {
setRunTimes(x => ({
...x,
sections: new Date()
}));
freshSections = await submitSectionsPrompt(inTopic, freshTitle, isBulk);
setRunTimes(x => ({
...x,
sections: null
}));
}
if (freshSections || noSections) {
setRunTimes(x => ({
...x,
content: new Date()
}));
freshContent = await submitContentPrompt(inTopic, freshTitle, freshSections, isBulk);
setRunTimes(x => ({
...x,
content: null
}));
if (freshContent) {
setRunTimes(x => ({
...x,
excerpt: new Date()
}));
freshExcerpt = await onSubmitPromptForExcerpt(inTopic, freshTitle, isBulk);
setRunTimes(x => ({
...x,
excerpt: null
}));
}
}
}
return {
title: freshTitle,
heads: freshSections,
content: freshContent,
excerpt: freshExcerpt
};
} catch (e) {
console.error(e);
setBusy(false);
setRunTimes({});
throw e;
}
};
/**
* Creates a new post with the given data on WordPress.
*/
const onSubmitNewPost = async (inTitle = title, inContent = content, inExcerpt = excerpt, isBulk = false) => {
setBusy(true);
abortController.current = new AbortController();
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_5__.apiUrl}/helpers/create_post`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_5__.restNonce,
signal: abortController.current.signal,
json: {
title: inTitle,
content: inContent,
excerpt: inExcerpt,
postType
}
});
if (!isBulk) {
setCreatedPostId(res.postId);
}
return res.postId;
} catch (err) {
if (err.name !== 'AbortError') {
console.error(err);
setError(err.message);
}
return null;
} finally {
setBusy(false);
}
};
/**
* Bulk generation for each topic in the list.
*/
const onBulkStart = async () => {
setCreatedPosts([]);
const tasks = topicsArray.map((topic, offset) => async () => {
console.log("Topic " + offset);
try {
const {
title,
content,
excerpt
} = await onGenerateAllClick(topic, true);
if (title && content && excerpt) {
const postId = await onSubmitNewPost(title, content, excerpt, true);
setCreatedPosts(x => [...x, {
postId,
topic,
title,
content,
excerpt
}]);
} else {
console.warn("Could not generate the post for: " + topic);
}
} catch (e) {
if (!confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.BULK_ERROR_CONFIRM.replace('{MESSAGE}', e.message))) {
bulkTasks.stop();
bulkTasks.reset();
setBusy(false);
}
}
return {
success: true
};
});
await bulkTasks.start(tasks);
bulkTasks.reset();
};
// ------------------------------------------------------------
// RENDER
// ------------------------------------------------------------
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoPage, {
nekoErrors: []
}, /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.AiNekoHeader, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.CONTENT_GENERATOR
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoWrapper, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.OptionsCheck, {
options: _app_settings__WEBPACK_IMPORTED_MODULE_5__.options
}), (_app_settings__WEBPACK_IMPORTED_MODULE_5__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_5__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_5__.options.intro_message) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoColumn, {
fullWidth: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoContainer, {
style: {
marginBottom: 0
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTypo, {
p: true
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.INTRO)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoColumn, {
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, jsxTemplates), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0
}
}, mode === 'bulk' ? _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.CONTEXT || 'Context' : _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.TOPIC), mode === 'bulk' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 0,
marginBottom: 10,
fontSize: 12,
opacity: 0.6
}
}, "Provide context that will be used for all generated posts to make them more accurate and relevant."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
name: "context",
disabled: isBusy || isLoadingPostTypes,
rows: 14,
value: context,
onChange: setTemplateProperty,
placeholder: "Example: This is for a cat enthusiast blog targeting pet owners and cat lovers. The tone should be friendly, informative, and occasionally playful. Include practical tips and scientific facts when relevant."
})) : /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
name: "topic",
disabled: isBusy || isLoadingPostTypes,
rows: 16,
value: topic,
onChange: setTemplateProperty,
placeholder: "Example: Write a comprehensive guide about adopting a rescue cat, covering the adoption process, preparing your home, first days together, and tips for helping the cat adjust to their new environment. Include advice for families with children or other pets."
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoButton, {
fullWidth: true,
disabled: !topic || mode === 'bulk' || isLoadingPostTypes,
isBusy: isBusy,
onClick: () => onGenerateAllClick(),
onStopClick: onStop,
startTime: runTimes === null || runTimes === void 0 ? void 0 : runTimes.all,
style: {
height: 50,
fontSize: 16,
flex: 4
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.GENERATE))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoColumn, {
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoQuickLinks, {
name: "mode",
value: mode,
disabled: isBusy,
onChange: setTemplateProperty
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.SINGLE_GENERATE,
value: "single"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.BULK_GENERATE,
value: "bulk",
count: topicsArray.length
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), mode === 'bulk' && /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 0,
marginBottom: 20
}
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.TOPICS_HELP)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoButton, {
disabled: isBusy || !topicsArray.length,
onClick: onBulkStart
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.GENERATE), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoProgress, {
busy: bulkTasks.busy,
style: {
marginLeft: 10,
flex: 'auto'
},
value: bulkTasks.value,
max: bulkTasks.max,
onStopClick: bulkTasks.stop
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement("h3", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.TOPICS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
name: "topics",
rows: 10,
value: topics,
onChange: setTemplateProperty,
placeholder: "Example:\nWhy Cats Make Perfect Companions\nUnderstanding Cat Body Language\nThe Science Behind Purring\nIndoor vs Outdoor Cats Debate\nBest Cat Breeds for Families"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_20__.NekoCheckbox, {
name: "topicsAreTitles",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.USE_TOPICS_AS_TITLES,
value: "1",
checked: topicsAreTitles,
onChange: setTemplateProperty
}), /*#__PURE__*/React.createElement("h3", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.GENERATED_POSTS), !createdPosts.length && /*#__PURE__*/React.createElement("i", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.NOTHING_YET), createdPosts.length > 0 && /*#__PURE__*/React.createElement("ul", null, createdPosts.map(x => /*#__PURE__*/React.createElement("li", {
key: x.postId
}, x.title, ' ', /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: `/?p=${x.postId}`,
rel: "noreferrer"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.VIEW), ' ', "or", ' ', /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: `/wp-admin/post.php?post=${x.postId}&action=edit`,
rel: "noreferrer"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.EDIT))))), mode === 'single' && /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.TITLE), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoInput, {
name: "title",
disabled: isBusy,
value: title,
onChange: setTemplateProperty,
placeholder: "The title will appear here after clicking 'Generate'"
}), titleMessage && /*#__PURE__*/React.createElement("div", {
className: "information"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.ADVICE, ": ", titleMessage), sectionsPromptFormat && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.StyledTitleWithButton, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.SECTIONS), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center'
}
}, formInputs.sectionsCount && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", {
style: {
margin: '0 5px 0 0'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.NUMBER_OF_SECTIONS, ":", ' '), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
scrolldown: true,
name: "sectionsCount",
disabled: isBusy,
style: {
marginRight: 10
},
value: sectionsCount,
description: "",
onChange: setTemplateProperty
}, [2, 3, 4, 5, 6, 8, 10, 12].map(num => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: num,
value: num,
label: num
})))), sectionsCount > 0 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoButton, {
variant: "secondary",
disabled: !title,
isBusy: isBusy,
startTime: runTimes === null || runTimes === void 0 ? void 0 : runTimes.sections,
onClick: () => submitSectionsPrompt()
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.GENERATE_SECTIONS))), sectionsCount > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
name: "sections",
disabled: isBusy,
rows: 4,
value: sections,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.SECTIONS_HELP,
onChange: setTemplateProperty,
placeholder: "Sections will appear here after clicking 'Generate'"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.StyledTitleWithButton, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.CONTENT), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center'
}
}, formInputs.paragraphsCount && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", {
style: {
margin: '0 5px 0 0'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.PARAGRAPHS_PER_SECTION, ":\xA0"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
scrolldown: true,
name: "paragraphsCount",
disabled: isBusy,
style: {
marginRight: 10
},
value: paragraphsCount,
description: "",
onChange: setTemplateProperty
}, [1, 2, 3, 4, 6, 8, 10].map(num => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: num,
value: num,
label: num
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoButton, {
variant: "secondary",
disabled: !title,
isBusy: isBusy,
startTime: runTimes === null || runTimes === void 0 ? void 0 : runTimes.content,
onClick: () => submitContentPrompt()
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.GENERATE_CONTENT))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
countable: "words",
disabled: isBusy,
rows: 12,
value: content,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.CONTENT_HELP,
onChange: setContent,
placeholder: "Your article content will appear here after clicking 'Generate'"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.StyledTitleWithButton, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.EXCERPT), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoButton, {
variant: "secondary",
disabled: !title,
isBusy: isBusy,
startTime: runTimes === null || runTimes === void 0 ? void 0 : runTimes.excerpt,
onClick: () => onSubmitPromptForExcerpt()
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.GENERATE_EXCERPT)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
disabled: isBusy,
value: excerpt,
onBlur: setExcerpt,
rows: 3,
placeholder: "The excerpt will appear here after clicking 'Generate'"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoButton, {
fullWidth: true,
style: {
height: 60,
fontSize: 16
},
onClick: () => onSubmitNewPost(),
isBusy: isBusy,
disabled: !title || !content
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.CREATE_POST))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoColumn, {
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.CONTENT), !formInputs.language && !formInputs.writingStyle && !formInputs.writingTone && !postType && /*#__PURE__*/React.createElement("div", {
style: {
fontSize: 11,
lineHeight: '14px'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.CONTENT_PARAMS_INTRO), formInputs.language && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.LANGUAGE, ":"), jsxLanguageSelector), formInputs.writingStyle && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.WRITING_STYLE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
scrolldown: true,
name: "writingStyle",
disabled: isBusy,
value: writingStyle,
description: "",
onChange: setTemplateProperty
}, _app_constants__WEBPACK_IMPORTED_MODULE_23__.WritingStyles.map(style => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: style.value,
value: style.value,
label: style.label
})))), formInputs.writingTone && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.WRITING_TONE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
scrolldown: true,
name: "writingTone",
disabled: isBusy,
value: writingTone,
description: "",
onChange: setTemplateProperty
}, _app_constants__WEBPACK_IMPORTED_MODULE_23__.WritingTones.map(tone => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: tone.value,
value: tone.value,
label: tone.label
})))), /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.POST_TYPE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
scrolldown: true,
disabled: isBusy,
name: "postType",
onChange: setPostType,
value: postType
}, postTypes === null || postTypes === void 0 ? void 0 : postTypes.map(pt => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: pt.type,
value: pt.type,
label: pt.name
}))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.StyledTitleWithButton, {
onClick: () => setShowModelParams(!showModelParams),
style: {
cursor: 'pointer'
}
}, /*#__PURE__*/React.createElement("h2", {
style: {
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.MODEL), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoIcon, {
icon: showModelParams ? "chevron-up" : "chevron-down",
height: "20",
style: {
opacity: 0.7
}
})), showModelParams && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.ENVIRONMENT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
scrolldown: true,
name: "envId",
value: envId ?? "",
onChange: setTemplateProperty
}, aiEnvironments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
value: "",
label: "Default"
})), /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.MODEL, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoSelect, {
name: "model",
value: model || "",
scrolldown: true,
disabled: !envId,
onChange: setTemplateProperty
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
value: "",
label: envId ? "None" : "Default"
}), completionModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoOption, {
key: x,
value: x.model,
label: x.name
}))), /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.TEMPERATURE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoInput, {
name: "temperature",
value: temperature,
type: "number",
onChange: setTemplateProperty,
onBlur: setTemplateProperty,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].HELP.TEMPERATURE
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.StyledTitleWithButton, {
onClick: () => setShowPrompts(!showPrompts),
style: {
cursor: 'pointer'
}
}, /*#__PURE__*/React.createElement("h2", {
style: {
marginBottom: 0
}
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.PROMPTS)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoIcon, {
icon: showPrompts ? "chevron-up" : "chevron-down",
height: "20",
style: {
opacity: 0.7
}
})), showPrompts && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
style: {
fontSize: 11,
lineHeight: '14px',
opacity: 0.6
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.PROMPTS_INTRO), /*#__PURE__*/React.createElement("label", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.PROMPT_TITLE)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
disabled: isBusy || (template === null || template === void 0 ? void 0 : template.id) === 'default',
name: "titlePromptFormat",
value: titlePromptFormat,
onChange: setTemplateProperty
}), /*#__PURE__*/React.createElement("label", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.PROMPT_SECTIONS)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
disabled: isBusy || (template === null || template === void 0 ? void 0 : template.id) === 'default',
name: "sectionsPromptFormat",
value: sectionsPromptFormat,
onChange: setTemplateProperty
}), /*#__PURE__*/React.createElement("label", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.PROMPT_CONTENT)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
disabled: isBusy || (template === null || template === void 0 ? void 0 : template.id) === 'default',
name: "contentPromptFormat",
value: contentPromptFormat,
onChange: setTemplateProperty
}), /*#__PURE__*/React.createElement("label", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.PROMPT_EXCERPT)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoTextArea, {
disabled: isBusy || (template === null || template === void 0 ? void 0 : template.id) === 'default',
name: "excerptPromptFormat",
value: excerptPromptFormat,
onChange: setTemplateProperty
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_10__.StyledTitleWithButton, {
onClick: () => setShowUsage(!showUsage),
style: {
cursor: 'pointer'
}
}, /*#__PURE__*/React.createElement("h2", {
style: {
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.USAGE), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoIcon, {
icon: showUsage ? "chevron-up" : "chevron-down",
height: "20",
style: {
opacity: 0.7
}
})), showUsage && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, {
tiny: true
}), jsxUsageCosts)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_25__.NekoModal, {
isOpen: createdPostId,
onRequestClose: () => setCreatedPostId(),
okButton: {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.EDIT_POST,
onClick: () => {
window.open(`/wp-admin/post.php?post=${createdPostId}&action=edit`, '_blank');
clearTemplate();
setCreatedPostId();
}
},
cancelButton: {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.CLOSE,
onClick: () => {
setCreatedPostId();
}
},
title: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.POST_CREATED,
content: /*#__PURE__*/React.createElement("p", null, _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].CONTENT_GENERATOR.POST_CREATED_AS_DRAFT)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_25__.NekoModal, {
isOpen: error,
onRequestClose: () => {
setError();
},
okButton: {
onClick: () => {
setError();
}
},
title: _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.ERROR,
content: /*#__PURE__*/React.createElement("p", null, error)
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ContentGenerator);
/***/ }),
/***/ "./app/js/screens/ImageGenerator.js":
/*!******************************************!*\
!*** ./app/js/screens/ImageGenerator.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Page.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _styles_CommonStyles__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../styles/CommonStyles */ "./app/js/styles/CommonStyles.js");
/* harmony import */ var _styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _components_Templates__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/Templates */ "./app/js/components/Templates.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useState,
useEffect,
useMemo,
useRef
} = wp.element;
// NekoUI
const ImagesCount = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 40, 60, 80, 100];
function generateFilename(prompt, maxLength = 42) {
let cleaned = prompt.replace(/[\s|,]+/g, '-');
cleaned = cleaned.replace(/--+/g, '-');
const words = cleaned.split("-");
let filename = words[0];
let i = 1;
while (i < words.length && words[i] && filename.length + words[i].length < maxLength) {
filename += "-" + words[i];
i++;
}
if (filename.length > maxLength + 1) {
filename = filename.slice(0, maxLength + 2);
}
return filename;
}
const StyledInputWrapper = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
margin-bottom: 5px;
label {
margin-bottom: 5px;
display: block;
}
`;
const StyledMaskContainer = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
position: relative;
width: 100%;
margin-bottom: 10px;
img {
width: 100%;
display: block;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: ${props => props.maskMode ? 'none' : 'default'};
pointer-events: ${props => props.maskMode ? 'auto' : 'none'};
}
`;
const StyledBrushCursor = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
position: absolute;
pointer-events: none;
border: 2px solid rgba(255, 0, 0, 0.8);
border-radius: 50%;
transform: translate(-50%, -50%);
opacity: ${props => props.visible ? 1 : 0};
transition: opacity 0.1s;
`;
const ImageGenerator = () => {
var _currentModel$resolut, _currentModel$resolut2, _currentModel$model;
const {
template,
setTemplate,
jsxTemplates
} = (0,_components_Templates__WEBPACK_IMPORTED_MODULE_1__["default"])('imagesGenerator');
const [error, setError] = useState();
const searchParams = new URLSearchParams(window.location.search);
const editId = searchParams.get('editId');
const [mode, setMode] = useState(editId ? 'edit' : 'generate');
const [infoModal, setInfoModal] = useState(false);
const [editImageUrl, setEditImageUrl] = useState();
const [continuousMode, setContinuousMode] = useState(true);
const [busy, setBusy] = useState(false);
const [busyMediaLibrary, setBusyMediaLibrary] = useState(false);
const [busyMediaLibraryEdit, setBusyMediaLibraryEdit] = useState(false);
const [busyMetadata, setBusyMetadata] = useState(false);
const aiEnvironments = (_app_settings__WEBPACK_IMPORTED_MODULE_2__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_2__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_2__.options.ai_envs) || [];
const {
imageModels,
getModel
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.useModels)(_app_settings__WEBPACK_IMPORTED_MODULE_2__.options, (template === null || template === void 0 ? void 0 : template.envId) || null);
const currentModel = getModel(template === null || template === void 0 ? void 0 : template.model);
const [taskQueue, setTaskQueue] = useState([]);
// Results
const [urls, setUrls] = useState([]);
const [selectedUrl, setSelectedUrl] = useState();
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [caption, setCaption] = useState('');
const [alt, setAlt] = useState('');
const [filename, setFilename] = useState('');
const [createdMediaIds, setCreatedMediaIds] = useState([]);
const [maskMode, setMaskMode] = useState(false);
const [maskData, setMaskData] = useState(null);
const [brushSize, setBrushSize] = useState(30);
const [showModelParams, setShowModelParams] = useState(true);
const [showSettings, setShowSettings] = useState(true);
const [cursorPosition, setCursorPosition] = useState({
x: 0,
y: 0,
visible: false
});
const canvasRef = useRef();
const imageRef = useRef();
const strokeLayerRef = useRef();
const strokesRef = useRef([]); // Store all completed strokes
const prompt = template === null || template === void 0 ? void 0 : template.prompt;
// Brush settings
const BRUSH_HARDNESS = 0.5; // 0 = soft, 1 = hard
const MIN_BRUSH_SIZE = 5;
const MAX_BRUSH_SIZE = 200;
const BRUSH_SIZE_STEP = 5;
const [totalImagesToGenerate, setTotalImagesToGenerate] = useState(1);
const [totalTasks, setTotalTasks] = useState(0);
const [processedTasks, setProcessedTasks] = useState(0);
const abortController = useRef();
const onStop = () => {
var _abortController$curr;
(_abortController$curr = abortController.current) === null || _abortController$curr === void 0 || _abortController$curr.abort();
setTaskQueue([]);
setTotalTasks(0);
setProcessedTasks(0);
setBusy(false);
};
const currentStyle = (template === null || template === void 0 ? void 0 : template.style) ?? null;
const setPrompt = value => {
setTemplate({
...template,
prompt: value
});
};
const setTemplateProperty = (value, property) => {
setTemplate(x => {
const newTemplate = {
...x,
[property]: value
};
// When envId is set to empty (Default), reset model to empty as well
if (property === 'envId' && value === '') {
newTemplate.model = '';
newTemplate.resolution = '';
}
// When model changes, reset resolution
if (property === 'model') {
newTemplate.resolution = '';
}
return newTemplate;
});
};
// Set default values for image metadata
useEffect(() => {
if (selectedUrl) {
const index = urls.indexOf(selectedUrl) + 1;
const newFilename = (generateFilename(prompt).toLowerCase() || 'image') + '.png';
setFilename(newFilename);
setTitle(`Untitled Image #${index || 1}`);
setDescription(prompt || '');
setCaption('');
setAlt('');
}
}, [selectedUrl]);
// Load image edit URL if editId is provided
useEffect(() => {
if (editId) {
fetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.restUrl}/wp/v2/media/${editId}`).then(res => res.json()).then(data => setEditImageUrl(data.source_url));
}
}, [editId]);
// Initialize canvas when image loads
useEffect(() => {
if (editImageUrl && imageRef.current && canvasRef.current) {
const img = imageRef.current;
const canvas = canvasRef.current;
img.onload = () => {
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
// Clear canvas to transparent
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Create stroke layer canvas
if (!strokeLayerRef.current) {
strokeLayerRef.current = document.createElement('canvas');
}
strokeLayerRef.current.width = canvas.width;
strokeLayerRef.current.height = canvas.height;
};
}
}, [editImageUrl]);
// Handle keyboard shortcuts for brush size
useEffect(() => {
if (!maskMode) return;
const handleKeyDown = e => {
if (e.key === '[') {
e.preventDefault();
setBrushSize(size => Math.max(MIN_BRUSH_SIZE, size - BRUSH_SIZE_STEP));
} else if (e.key === ']') {
e.preventDefault();
setBrushSize(size => Math.min(MAX_BRUSH_SIZE, size + BRUSH_SIZE_STEP));
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [maskMode]);
// Create proper mask canvas (separate from display canvas)
const createMaskBlob = callback => {
const canvas = canvasRef.current;
const maskCanvas = document.createElement('canvas');
maskCanvas.width = canvas.width;
maskCanvas.height = canvas.height;
const maskCtx = maskCanvas.getContext('2d');
// Fill with opaque black (areas to keep)
maskCtx.fillStyle = 'black';
maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
// Get the drawing data and create transparent areas where red was drawn
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const maskImageData = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height);
// Where we drew red, make the mask transparent
for (let i = 0; i < imageData.data.length; i += 4) {
const r = imageData.data[i];
const a = imageData.data[i + 3];
// If there's red color with some opacity, make it transparent in the mask
if (r > 200 && a > 100) {
maskImageData.data[i] = 0; // R
maskImageData.data[i + 1] = 0; // G
maskImageData.data[i + 2] = 0; // B
maskImageData.data[i + 3] = 0; // A (transparent)
}
}
maskCtx.putImageData(maskImageData, 0, 0);
maskCanvas.toBlob(callback, 'image/png');
};
// Create a separate canvas for brush strokes
const brushCanvasRef = useRef();
// Initialize brush canvas
useEffect(() => {
if (editImageUrl && imageRef.current && brushCanvasRef.current) {
const img = imageRef.current;
const canvas = brushCanvasRef.current;
img.onload = () => {
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
};
}
}, [editImageUrl]);
// Draw a gradient brush stroke
const drawGradientBrush = (ctx, x, y, size, hardness) => {
const gradient = ctx.createRadialGradient(x, y, 0, x, y, size / 2);
if (hardness >= 1) {
gradient.addColorStop(0, 'rgba(255, 0, 0, 1)');
gradient.addColorStop(1, 'rgba(255, 0, 0, 1)');
} else {
const innerStop = hardness * 0.5;
gradient.addColorStop(0, 'rgba(255, 0, 0, 1)');
gradient.addColorStop(innerStop, 'rgba(255, 0, 0, 1)');
gradient.addColorStop(1, 'rgba(255, 0, 0, 0)');
}
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(x, y, size / 2, 0, Math.PI * 2);
ctx.fill();
};
// Create brush texture with gradient
const createBrushTexture = (size, hardness) => {
const brushCanvas = document.createElement('canvas');
brushCanvas.width = size;
brushCanvas.height = size;
const brushCtx = brushCanvas.getContext('2d');
const gradient = brushCtx.createRadialGradient(size / 2, size / 2, 0, size / 2, size / 2, size / 2);
if (hardness >= 1) {
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 1)');
} else {
const innerStop = hardness * 0.5;
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
gradient.addColorStop(innerStop, 'rgba(255, 255, 255, 1)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
}
brushCtx.fillStyle = gradient;
brushCtx.fillRect(0, 0, size, size);
return brushCanvas;
};
// Handle mask drawing
const handleCanvasMouseDown = e => {
if (!maskMode) return;
const canvas = canvasRef.current;
const rect = canvas.getBoundingClientRect();
const ctx = canvas.getContext('2d');
// Calculate scale factors
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
const scaledBrushSize = brushSize * scaleX;
const brushRadius = scaledBrushSize / 2;
let isDrawing = true;
let currentX = (e.clientX - rect.left) * scaleX;
let currentY = (e.clientY - rect.top) * scaleY;
// Time-based opacity settings
const OPACITY_INCREMENT = 0.05; // How much opacity increases per frame (faster now)
const MAX_OPACITY = 1.0;
const INITIAL_OPACITY = 0.5; // Start at 50% opacity
const FRAME_RATE = 60; // Target frame rate
// Animation frame ID for cancellation
let animationId = null;
// Function to apply brush with current opacity
const applyBrush = opacity => {
ctx.save();
ctx.globalAlpha = opacity;
drawGradientBrush(ctx, currentX, currentY, scaledBrushSize, BRUSH_HARDNESS);
ctx.restore();
};
// Time-based painting loop
let currentOpacity = INITIAL_OPACITY;
let isFirstPaint = true;
const paintLoop = () => {
if (!isDrawing) return;
if (isFirstPaint) {
// First paint at initial opacity
applyBrush(INITIAL_OPACITY);
isFirstPaint = false;
} else {
// Subsequent paints with increment
currentOpacity = Math.min(currentOpacity + OPACITY_INCREMENT, MAX_OPACITY);
applyBrush(OPACITY_INCREMENT);
}
// Continue the loop
animationId = requestAnimationFrame(paintLoop);
};
// Start the painting loop
paintLoop();
const handleMouseMove = e => {
if (!isDrawing) return;
const newX = (e.clientX - rect.left) * scaleX;
const newY = (e.clientY - rect.top) * scaleY;
const dx = newX - currentX;
const dy = newY - currentY;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 1) {
// Draw interpolated line
const steps = Math.ceil(distance / 2);
for (let i = 1; i <= steps; i++) {
const t = i / steps;
const x = currentX + dx * t;
const y = currentY + dy * t;
// Apply brush with initial opacity for smooth trails
ctx.save();
ctx.globalAlpha = INITIAL_OPACITY * 0.3; // 30% of initial opacity when moving fast
drawGradientBrush(ctx, x, y, scaledBrushSize, BRUSH_HARDNESS);
ctx.restore();
}
currentX = newX;
currentY = newY;
// Reset opacity when moving to new position
currentOpacity = INITIAL_OPACITY;
isFirstPaint = true;
}
};
const handleMouseUp = () => {
isDrawing = false;
// Cancel animation
if (animationId) {
cancelAnimationFrame(animationId);
}
// Create mask
createMaskBlob(blob => {
setMaskData(blob);
});
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
};
const toggleMaskMode = () => {
if (maskMode) {
// Clear mask
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
setMaskData(null);
setMaskMode(false);
} else {
setMaskMode(true);
}
};
const addToQueue = () => {
var _currentModel$tags;
if (!prompt) {
console.error("Prompt is empty, cannot add to queue.");
return;
}
if (mode === 'edit' && !(currentModel !== null && currentModel !== void 0 && (_currentModel$tags = currentModel.tags) !== null && _currentModel$tags !== void 0 && _currentModel$tags.includes('image-edit'))) {
setError('This model does not support image editing.');
return;
}
for (let i = 0; i < totalImagesToGenerate; i++) {
const newTask = {
prompt,
envId: template.envId,
model: template.model,
resolution: template.resolution,
style: template.style
};
setTaskQueue(queue => [...queue, newTask]);
}
setTotalTasks(prev => prev + totalImagesToGenerate);
};
const processQueue = async () => {
if (taskQueue.length === 0 || busy) return;
setBusy(true);
abortController.current = new AbortController();
const currentTask = taskQueue[0];
try {
const endpoint = mode === 'edit' ? 'image_edit' : 'images';
// Prepare request data
const requestData = {
env: 'admin-tools',
envId: currentTask.envId,
model: currentTask.model,
resolution: currentTask.resolution,
style: currentTask.style,
scope: 'admin-tools',
session: _app_settings__WEBPACK_IMPORTED_MODULE_2__.session,
message: currentTask.prompt,
maxResults: 1,
mediaId: editId,
local_download: null // Explicitly disable automatic media library saving
};
// Debug log
console.log('Image Edit Request:', {
mode,
endpoint,
hasMask: !!maskData,
editId,
requestData
});
let res;
if (mode === 'edit' && maskData) {
// If we have a mask, use FormData
const formData = new FormData();
Object.keys(requestData).forEach(key => {
if (requestData[key] !== null && requestData[key] !== undefined) {
// Convert to string to ensure proper FormData handling
formData.append(key, String(requestData[key]));
}
});
formData.append('mask', maskData, 'mask.png');
// Debug FormData contents
console.log('FormData contents:');
for (let [key, value] of formData.entries()) {
console.log(key, value);
}
// Use native fetch for FormData instead of nekoFetch
res = await fetch(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/ai/${endpoint}`, {
method: 'POST',
headers: {
'X-WP-Nonce': _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce
},
signal: abortController.current.signal,
body: formData
});
if (!res.ok) {
const errorData = await res.json();
throw new Error(errorData.message || 'Request failed');
}
res = await res.json();
} else {
// Otherwise use regular JSON
res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_4__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/ai/${endpoint}`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
signal: abortController.current.signal,
json: requestData
});
}
if (res.data && res.data.length > 0) {
setUrls(urls => [...urls, res.data[0]]);
}
setTaskQueue(queue => queue.slice(1));
setProcessedTasks(prev => prev + 1);
if (taskQueue.length === 1) {
setTotalTasks(0);
setProcessedTasks(0);
}
} catch (err) {
if (err.name !== 'AbortError' && !/aborted/i.test(err.message)) {
console.error(err);
setError(err.message + (taskQueue.length > 1 ? ' The other tasks will continue.' : ''));
setTaskQueue(queue => queue.slice(1));
setTotalTasks(totalTasks => totalTasks - 1);
}
} finally {
setBusy(false);
}
};
useEffect(() => {
if (taskQueue.length > 0 && !busy) {
processQueue();
}
}, [taskQueue, busy]);
const clearImages = () => {
setUrls([]);
};
const onGenerateMeta = async () => {
setBusyMetadata(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_4__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/helpers/generate_image_meta`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
json: {
url: selectedUrl
}
});
if (res !== null && res !== void 0 && res.data) {
setTitle(res.data.title || '');
setDescription(res.data.description || '');
setCaption(res.data.description || '');
setAlt(res.data.description || '');
if (res.data.filename) {
setFilename(res.data.filename);
}
}
} catch (err) {
if (err.name !== 'AbortError' && !/aborted/i.test(err.message)) {
console.error(err);
setError(err.message);
}
} finally {
setBusyMetadata(false);
}
};
const onAdd = async (andEdit = false) => {
setBusyMediaLibrary(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_4__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/helpers/create_image`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
json: {
url: selectedUrl,
title,
description,
caption,
alt,
filename
}
});
setCreatedMediaIds([...createdMediaIds, {
id: res.attachmentId,
url: selectedUrl
}]);
if (andEdit) {
// Redirect to Images Generator edit mode with this image
window.location.href = `edit.php?page=mwai_images_generator&editId=${res.attachmentId}`;
}
setSelectedUrl();
} catch (err) {
if (err.name !== 'AbortError' && !/aborted/i.test(err.message)) {
console.error(err);
setError(err.message);
}
} finally {
setBusyMediaLibrary(false);
}
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoPage, {
nekoErrors: []
}, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_6__.AiNekoHeader, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.IMAGES_GENERATOR
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoWrapper, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.OptionsCheck, {
options: _app_settings__WEBPACK_IMPORTED_MODULE_2__.options
}), (_app_settings__WEBPACK_IMPORTED_MODULE_2__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_2__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_2__.options.intro_message) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoColumn, {
fullWidth: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoContainer, {
style: {
marginBottom: 0
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoTypo, {
p: true
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_4__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.IMAGES_GENERATOR_INTRO)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoColumn, {
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_11__.StyledSidebar, null, mode === 'edit' && editImageUrl && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StyledMaskContainer, {
maskMode: maskMode,
onMouseMove: e => {
if (maskMode) {
const rect = e.currentTarget.getBoundingClientRect();
setCursorPosition({
x: e.clientX - rect.left,
y: e.clientY - rect.top,
visible: true
});
}
},
onMouseLeave: () => setCursorPosition(prev => ({
...prev,
visible: false
}))
}, /*#__PURE__*/React.createElement("img", {
ref: imageRef,
src: editImageUrl
}), /*#__PURE__*/React.createElement("canvas", {
ref: canvasRef,
onMouseDown: handleCanvasMouseDown
}), /*#__PURE__*/React.createElement(StyledBrushCursor, {
visible: cursorPosition.visible && maskMode,
style: {
left: cursorPosition.x,
top: cursorPosition.y,
width: brushSize,
height: brushSize
}
})), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
gap: 5,
marginBottom: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: toggleMaskMode,
style: {
flex: 2
}
}, maskMode ? 'Remove Mask' : 'Create Mask'), maskMode && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: () => setBrushSize(size => Math.max(MIN_BRUSH_SIZE, size - BRUSH_SIZE_STEP)),
style: {
flex: 1
},
title: "Decrease brush size"
}, "\u2212"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '0 10px',
border: '1px solid #ddd',
borderRadius: 4,
background: '#f5f5f5',
minWidth: 40
}
}, brushSize), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: () => setBrushSize(size => Math.min(MAX_BRUSH_SIZE, size + BRUSH_SIZE_STEP)),
style: {
flex: 1
},
title: "Increase brush size"
}, "+"))), maskMode && /*#__PURE__*/React.createElement("div", {
style: {
fontSize: 11,
opacity: 0.6,
marginBottom: 10,
textAlign: 'center'
}
}, "Use [ and ] keys to adjust brush size")), mode !== 'edit' && jsxTemplates), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, null), /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_11__.StyledSidebar, null, !selectedUrl && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0
}
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_4__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.PROMPT)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoTextArea, {
value: prompt,
onChange: setPrompt,
rows: 10,
placeholder: "Enter your prompt here..."
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_6__.StyledTitleWithButton, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
flex: 1
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
gap: 5
}
}, busy && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
disabled: !prompt,
onClick: addToQueue,
style: {
flex: 1
}
}, "Add to Queue"), urls.length > 0 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: clearImages,
style: {
flex: 1
}
}, "Clear")), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSelect, {
scrolldown: true,
id: "totalImagesToGenerate",
name: "totalImagesToGenerate",
style: {
width: '100%'
},
value: totalImagesToGenerate,
onChange: value => setTotalImagesToGenerate(value)
}, ImagesCount.map(count => {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: count,
id: count,
value: count,
label: `${count} ${count > 1 ? 'Images' : 'Image'}`
});
}))))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, null), /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_11__.StyledSidebar, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
disabled: !prompt,
onClick: addToQueue,
onStopClick: onStop,
isBusy: busy,
style: {
height: 50,
fontSize: 16,
flex: 4
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.GENERATE))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoColumn, {
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoQuickLinks, {
value: mode,
onChange: value => {
if (value === 'generate') {
location.href = 'edit.php?page=mwai_images_generator';
} else if (value === 'edit') {
if (!editId) {
setInfoModal(true);
} else {
setMode('edit');
}
}
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoLink, {
title: "Create",
value: "generate"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoLink, {
title: "Editor",
value: "edit"
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoProgress, {
busy: busy,
value: processedTasks,
max: totalTasks,
onStopClick: onStop,
status: () => `${processedTasks} / ${totalTasks}`
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, null), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoModal, {
isOpen: !!selectedUrl,
title: title || 'Image Preview',
size: "larger",
onRequestClose: () => setSelectedUrl(),
hideButtons: true,
content: selectedUrl && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginBottom: 20
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("a", {
href: selectedUrl,
target: "_blank",
rel: "noreferrer"
}, /*#__PURE__*/React.createElement("img", {
src: selectedUrl,
style: {
maxWidth: '100%',
maxHeight: '60vh',
objectFit: 'contain'
}
}))), /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
marginLeft: 10,
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement(StyledInputWrapper, null, /*#__PURE__*/React.createElement("label", null, "Title:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoInput, {
value: title,
onChange: setTitle
})), /*#__PURE__*/React.createElement(StyledInputWrapper, null, /*#__PURE__*/React.createElement("label", null, "Caption:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoTextArea, {
value: caption,
onBlur: setCaption,
rows: 2
})), /*#__PURE__*/React.createElement(StyledInputWrapper, null, /*#__PURE__*/React.createElement("label", null, "Description:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoTextArea, {
value: description,
onBlur: setDescription,
rows: 2
})), /*#__PURE__*/React.createElement(StyledInputWrapper, null, /*#__PURE__*/React.createElement("label", null, "Alternative Text:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoTextArea, {
value: alt,
onBlur: setAlt,
rows: 2
})), /*#__PURE__*/React.createElement(StyledInputWrapper, null, /*#__PURE__*/React.createElement("label", null, "Filename:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoInput, {
value: filename,
onChange: setFilename
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: onGenerateMeta,
isBusy: busyMetadata
}, "Generate Meta"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, {
tiny: true
}))), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
gap: 10,
justifyContent: 'flex-end',
borderTop: '1px solid #e0e0e0',
paddingTop: 20,
marginTop: 20
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: () => setSelectedUrl(),
secondary: true
}, "Close"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: () => {
setBusyMediaLibraryEdit(true);
onAdd(true).finally(() => setBusyMediaLibraryEdit(false));
},
isBusy: busyMediaLibraryEdit,
secondary: true
}, "Add to Media Library & Edit"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
onClick: () => onAdd(false),
isBusy: busyMediaLibrary
}, "Add to Media Library")))
}), !selectedUrl && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_6__.StyledGallery, null, urls.map(url => {
const media = createdMediaIds.find(m => m.url === url);
return /*#__PURE__*/React.createElement("div", {
key: url,
className: "image-wrapper",
onClick: () => setSelectedUrl(url)
}, /*#__PURE__*/React.createElement("img", {
src: url
}), media && /*#__PURE__*/React.createElement("div", {
className: "media-label",
onClick: e => {
e.stopPropagation();
window.open(`/wp-admin/post.php?post=${media.id}&action=edit`, '_blank');
}
}, "Media #", media.id), /*#__PURE__*/React.createElement("div", {
className: "delete-icon",
onClick: e => {
e.stopPropagation();
setUrls(urls.filter(u => u !== url));
setCreatedMediaIds(createdMediaIds.filter(m => m.url !== url));
}
}, "\xD7"));
}), [...Array(Math.max(3 - urls.length, 0)).keys()].map((_, i) => /*#__PURE__*/React.createElement("div", {
key: i,
className: "empty-image"
})))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoColumn, {
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_11__.StyledSidebar, {
style: {
marginBottom: 25
}
}, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_6__.StyledTitleWithButton, {
onClick: () => setShowModelParams(!showModelParams),
style: {
cursor: 'pointer'
}
}, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0,
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.MODEL), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_20__.NekoIcon, {
icon: showModelParams ? "chevron-up" : "chevron-down",
height: "20",
style: {
opacity: 0.7
}
})), showModelParams && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.ENVIRONMENT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSelect, {
scrolldown: true,
name: "envId",
value: (template === null || template === void 0 ? void 0 : template.envId) ?? "",
onChange: setTemplateProperty
}, aiEnvironments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
value: "",
label: "Default"
})), /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.MODEL, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSelect, {
scrolldown: true,
name: "model",
value: (template === null || template === void 0 ? void 0 : template.model) || "",
disabled: !(template !== null && template !== void 0 && template.envId),
onChange: setTemplateProperty
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
value: "",
label: template !== null && template !== void 0 && template.envId ? "None" : "Default"
}), imageModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))), (currentModel === null || currentModel === void 0 || (_currentModel$resolut = currentModel.resolutions) === null || _currentModel$resolut === void 0 ? void 0 : _currentModel$resolut.length) > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.RESOLUTION, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSelect, {
scrolldown: true,
name: "resolution",
value: (template === null || template === void 0 ? void 0 : template.resolution) || "",
onChange: setTemplateProperty
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
value: "",
label: "Default"
}), currentModel === null || currentModel === void 0 || (_currentModel$resolut2 = currentModel.resolutions) === null || _currentModel$resolut2 === void 0 ? void 0 : _currentModel$resolut2.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: x.name,
value: x.name,
label: x.label
})))), (template === null || template === void 0 ? void 0 : template.resolution) === 'custom' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, "Custom Resolution:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoInput, {
name: "customResolution",
value: template === null || template === void 0 ? void 0 : template.customResolution,
onChange: value => setTemplateProperty(value, 'customResolution')
})), (currentModel === null || currentModel === void 0 || (_currentModel$model = currentModel.model) === null || _currentModel$model === void 0 ? void 0 : _currentModel$model.startsWith('dall-e-3')) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.STYLE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSelect, {
scrolldown: true,
name: "style",
value: currentStyle,
onChange: setTemplateProperty
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: 'none',
value: null,
label: 'None'
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: 'natural',
value: 'natural',
label: 'Natural'
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoOption, {
key: 'vivid',
value: 'vivid',
label: 'Vivid'
}))))), /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_11__.StyledSidebar, {
style: {
marginBottom: 25
}
}, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_6__.StyledTitleWithButton, {
onClick: () => setShowSettings(!showSettings),
style: {
cursor: 'pointer'
}
}, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0,
marginBottom: 0
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.SETTINGS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_20__.NekoIcon, {
icon: showSettings ? "chevron-up" : "chevron-down",
height: "20",
style: {
opacity: 0.7
}
})), showSettings && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoCheckbox, {
id: "continuous_mode ",
label: "Continuous",
value: "1",
checked: continuousMode,
description: /*#__PURE__*/React.createElement("span", {
style: {
fontSize: 11,
opacity: 0.6
}
}, "New images will be added to the already generated images."),
onChange: setContinuousMode
}))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoModal, {
isOpen: error,
onRequestClose: () => {
setError();
},
okButton: {
onClick: () => {
setError();
}
},
title: "Error",
content: /*#__PURE__*/React.createElement("p", null, error)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoModal, {
isOpen: infoModal,
onRequestClose: () => setInfoModal(false),
okButton: {
onClick: () => setInfoModal(false)
},
title: "Image Edit",
content: /*#__PURE__*/React.createElement("p", null, "Editing images is only available via the Edit action in the Media Library and is still in active development.")
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ImageGenerator);
/***/ }),
/***/ "./app/js/screens/Playground.js":
/*!**************************************!*\
!*** ./app/js/screens/Playground.js ***!
\**************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Page.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _styles_CommonStyles__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../styles/CommonStyles */ "./app/js/styles/CommonStyles.js");
/* harmony import */ var _styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _components_Templates__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/Templates */ "./app/js/components/Templates.js");
/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../i18n */ "./app/i18n.js");
/* harmony import */ var _components_UsageCosts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/UsageCosts */ "./app/js/components/UsageCosts.js");
/* harmony import */ var _app_helpers__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @app/helpers */ "./app/js/helpers.js");
// React & Vendor Libs
const {
useState,
useEffect,
useRef
} = wp.element;
// NekoUI
// AI Engine
const StyledTextArea = (0,styled_components__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoTextArea))`
.neko-textarea-container {
textarea {
color: white;
font-size: 13px;
padding: 10px;
font-family: monospace;
background: #333d4e;
border: none;
&:focus {
background-color: #333d4e;
}
}
}
`;
const Dashboard = () => {
const {
template,
setTemplate,
jsxTemplates
} = (0,_components_Templates__WEBPACK_IMPORTED_MODULE_2__["default"])('playground');
const [completion, setCompletion] = useState("");
const [busy, setBusy] = useState(false);
const [continuousEntry, setContinuousEntry] = useState('');
const [startTime, setStartTime] = useState();
const [error, setError] = useState();
const [showSettings, setShowSettings] = useState(true);
const abortController = useRef();
// Template Variables
const prompt = (template === null || template === void 0 ? void 0 : template.prompt) ?? "";
const model = (template === null || template === void 0 ? void 0 : template.model) ?? "gpt-3.5-turbo";
const mode = (template === null || template === void 0 ? void 0 : template.mode) ?? "query";
const temperature = (template === null || template === void 0 ? void 0 : template.temperature) ?? 1;
const envId = (template === null || template === void 0 ? void 0 : template.envId) ?? "";
const stopSequence = (template === null || template === void 0 ? void 0 : template.stopSequence) ?? "";
const maxTokens = (template === null || template === void 0 ? void 0 : template.maxTokens) ?? 2048;
// AI Environment
const {
calculatePrice,
completionModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.useModels)(_app_settings__WEBPACK_IMPORTED_MODULE_4__.options, envId || null);
const {
addUsage,
jsxUsageCosts
} = (0,_components_UsageCosts__WEBPACK_IMPORTED_MODULE_5__["default"])(calculatePrice);
const aiEnvironments = (_app_settings__WEBPACK_IMPORTED_MODULE_4__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_4__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_4__.options.ai_envs) || [];
const setTemplateProperty = (value, property) => {
const newTemplate = {
...template,
[property]: value
};
// When envId is set to empty (Default), reset model to empty as well
if (property === 'envId' && value === '') {
newTemplate.model = '';
}
setTemplate(newTemplate);
};
const setPrompt = prompt => {
setTemplate({
...template,
prompt: prompt
});
};
const onPushContinuousEntry = () => {
const newPrompt = prompt + "Human: " + continuousEntry;
setPrompt(newPrompt);
setContinuousEntry("");
onSubmitPrompt(newPrompt);
};
useEffect(() => {
if (template) {
setCompletion("");
}
}, [template]);
// const onReset_usage = () => {
// setSessionCost(0);
// setLastCost(0);
// }
const onStop = () => {
var _abortController$curr;
(_abortController$curr = abortController.current) === null || _abortController$curr === void 0 || _abortController$curr.abort();
setStartTime();
setBusy(false);
};
const onSubmitPrompt = async (promptToUse = prompt) => {
abortController.current = new AbortController();
setBusy(true);
setStartTime(new Date());
try {
var _finalRes$usage, _finalRes$usage2;
// TODO: Check if people complain about not having the Max Tokens and Stop Sequence settings.
// const stop = stopSequence.replace(/\\n/g, '\n');
const streamCallback = !_app_settings__WEBPACK_IMPORTED_MODULE_4__.stream ? null : content => {
setCompletion(content);
};
const res = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_6__.mwaiFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_4__.apiUrl}/ai/completions`, {
scope: 'playground',
session: _app_settings__WEBPACK_IMPORTED_MODULE_4__.session,
message: promptToUse,
temperature,
envId: envId,
model,
// maxTokens: maxTokens,
// stop: stop,
stream: _app_settings__WEBPACK_IMPORTED_MODULE_4__.stream
}, _app_settings__WEBPACK_IMPORTED_MODULE_4__.restNonce, _app_settings__WEBPACK_IMPORTED_MODULE_4__.stream, abortController.current.signal);
const debug = false;
const finalRes = await (0,_app_helpers__WEBPACK_IMPORTED_MODULE_6__.mwaiHandleRes)(res, streamCallback, debug ? "PLAYGROUND" : null, null, debug);
if ((finalRes === null || finalRes === void 0 ? void 0 : finalRes.success) === false) {
throw new Error(finalRes === null || finalRes === void 0 ? void 0 : finalRes.message);
}
console.log("Completions", {
prompt: promptToUse,
result: finalRes
});
if (mode === 'continuous') {
setPrompt(promptToUse + '\n' + finalRes.data + '\n');
} else {
setCompletion(finalRes.data);
}
addUsage(model, (finalRes === null || finalRes === void 0 || (_finalRes$usage = finalRes.usage) === null || _finalRes$usage === void 0 ? void 0 : _finalRes$usage.prompt_tokens) || 0, (finalRes === null || finalRes === void 0 || (_finalRes$usage2 = finalRes.usage) === null || _finalRes$usage2 === void 0 ? void 0 : _finalRes$usage2.completion_tokens) || 0);
} catch (err) {
if (err.name !== 'AbortError') {
setError(err.message);
}
}
setStartTime();
setBusy(false);
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoPage, {
nekoErrors: []
}, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_8__.AiNekoHeader, {
title: _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.PLAYGROUND
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoWrapper, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.OptionsCheck, {
options: _app_settings__WEBPACK_IMPORTED_MODULE_4__.options
}), (_app_settings__WEBPACK_IMPORTED_MODULE_4__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_4__.options === void 0 ? void 0 : _app_settings__WEBPACK_IMPORTED_MODULE_4__.options.intro_message) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoColumn, {
fullWidth: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoContainer, {
style: {
marginBottom: 0
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoTypo, {
p: true
}, (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].PLAYGROUND.INTRO)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoColumn, null, /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, jsxTemplates), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoButton, {
fullWidth: true,
onClick: onSubmitPrompt,
onStopClick: onStop,
isBusy: busy,
startTime: startTime,
style: {
height: 50,
fontSize: 16,
flex: 4
}
}, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.GENERATE))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoColumn, {
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, mode !== 'continuous' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StyledTextArea, {
rows: 12,
onChange: setPrompt,
value: prompt
})), mode === 'continuous' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StyledTextArea, {
rows: 18,
onChange: setPrompt,
value: prompt
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement("span", {
className: "dashicons dashicons-format-continuous",
style: {
position: 'absolute',
color: 'white',
zIndex: 200,
fontSize: 28,
marginTop: 12,
marginLeft: 10
}
}), /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledNekoInput, {
name: "continuousEntry",
value: continuousEntry,
onChange: setContinuousEntry,
onEnter: onPushContinuousEntry,
disabled: busy
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), (completion || busy) && /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_app_helpers__WEBPACK_IMPORTED_MODULE_6__.OutputHandler, {
content: completion,
isStreaming: _app_settings__WEBPACK_IMPORTED_MODULE_4__.stream && busy
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoColumn, null, /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_8__.StyledTitleWithButton, {
onClick: () => setShowSettings(!showSettings),
style: {
cursor: 'pointer'
}
}, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0,
marginBottom: 0
}
}, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.SETTINGS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoIcon, {
icon: showSettings ? "chevron-up" : "chevron-down",
height: "20",
style: {
opacity: 0.7
}
})), showSettings && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("label", null, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.ENVIRONMENT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoSelect, {
scrolldown: true,
name: "envId",
value: envId ?? "",
onChange: setTemplateProperty
}, aiEnvironments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
value: "",
label: "Default"
})), /*#__PURE__*/React.createElement("label", null, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.MODEL, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoSelect, {
name: "model",
value: model || "",
scrolldown: true,
disabled: !envId,
onChange: setTemplateProperty
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
value: "",
label: envId ? "None" : "Default"
}), completionModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))), /*#__PURE__*/React.createElement("label", null, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.TEMPERATURE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoInput, {
name: "temperature",
value: temperature,
type: "number",
onChange: value => setTemplateProperty(parseFloat(value), 'temperature'),
description: /*#__PURE__*/React.createElement("span", {
style: {
fontSize: 11,
opacity: 0.6
}
}, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].HELP.TEMPERATURE)
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, null), /*#__PURE__*/React.createElement(_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledSidebar, null, /*#__PURE__*/React.createElement(_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_8__.StyledTitleWithButton, null, /*#__PURE__*/React.createElement("h2", {
style: {
marginTop: 0,
marginBottom: 0
}
}, _i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.USAGE)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoSpacer, {
tiny: true
}), jsxUsageCosts))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_20__.NekoModal, {
isOpen: error,
onRequestClose: () => {
setError();
},
okButton: {
onClick: () => {
setError();
}
},
title: "Error",
content: /*#__PURE__*/React.createElement("p", null, error)
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Dashboard);
/***/ }),
/***/ "./app/js/screens/Settings.js":
/*!************************************!*\
!*** ./app/js/screens/Settings.js ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/CheckboxGroup.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Page.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! @common */ "./common/js/components/LicenseBlock.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @app/styles/CommonStyles */ "./app/js/styles/CommonStyles.js");
/* harmony import */ var _app_screens_finetunes_Finetunes__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! @app/screens/finetunes/Finetunes */ "./app/js/screens/finetunes/Finetunes.js");
/* harmony import */ var _app_screens_misc_Moderation__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! @app/screens/misc/Moderation */ "./app/js/screens/misc/Moderation.js");
/* harmony import */ var _app_screens_embeddings_Embeddings__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @app/screens/embeddings/Embeddings */ "./app/js/screens/embeddings/Embeddings.js");
/* harmony import */ var _app_components_UsageWidget__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @app/components/UsageWidget */ "./app/js/components/UsageWidget.js");
/* harmony import */ var _app_screens_discussions_Discussions__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @app/screens/discussions/Discussions */ "./app/js/screens/discussions/Discussions.js");
/* harmony import */ var _chatbots_Chatbots__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./chatbots/Chatbots */ "./app/js/screens/chatbots/Chatbots.js");
/* harmony import */ var _app_screens_queries_Insights__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @app/screens/queries/Insights */ "./app/js/screens/queries/Insights.js");
/* harmony import */ var _settings_DevToolsTab__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./settings/DevToolsTab */ "./app/js/screens/settings/DevToolsTab.js");
/* harmony import */ var _embeddings_Environments__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./embeddings/Environments */ "./app/js/screens/embeddings/Environments.js");
/* harmony import */ var _ai_Environments__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./ai/Environments */ "./app/js/screens/ai/Environments.js");
/* harmony import */ var _orchestration_MCPServers__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./orchestration/MCPServers */ "./app/js/screens/orchestration/MCPServers.js");
/* harmony import */ var _app_components_MCPFunctions__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! @app/components/MCPFunctions */ "./app/js/components/MCPFunctions.js");
/* harmony import */ var _app_components_CopyableField__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @app/components/CopyableField */ "./app/js/components/CopyableField.js");
/* harmony import */ var _misc_Transcription__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./misc/Transcription */ "./app/js/screens/misc/Transcription.js");
/* harmony import */ var _misc_Search__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./misc/Search */ "./app/js/screens/misc/Search.js");
/* harmony import */ var _assistants_Assistants__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./assistants/Assistants */ "./app/js/screens/assistants/Assistants.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* harmony import */ var _Addons__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./Addons */ "./app/js/screens/Addons.js");
// React & Vendor Libs
const {
useMemo,
useState,
useEffect,
useCallback
} = wp.element;
// NekoUI
const defaultEnvironmentSections = [{
envKey: 'ai_fast_default_env',
modelKey: 'ai_fast_default_model',
defaultModel: 'gpt-4.1-nano'
}, {
envKey: 'ai_embeddings_default_env',
modelKey: 'ai_embeddings_default_model',
defaultModel: 'text-embedding-ada-002'
}, {
envKey: 'ai_vision_default_env',
modelKey: 'ai_vision_default_model',
defaultModel: 'gpt-4o-mini'
}, {
envKey: 'ai_images_default_env',
modelKey: 'ai_images_default_model',
defaultModel: 'dall-e-3-hd'
}, {
envKey: 'ai_audio_default_env',
modelKey: 'ai_audio_default_model',
defaultModel: 'whisper-1'
}, {
envKey: 'ai_json_default_env',
modelKey: 'ai_json_default_model',
defaultModel: 'gpt-4o-mini'
}];
const proOptions = ['module_forms', 'module_statistics', 'module_embeddings', 'module_assistants', 'module_orchestration'];
const Settings = () => {
var _options$ai_envs, _options$ai_envs2, _options$embeddings_s, _options$embeddings_s2, _options$embeddings_s3, _options$embeddings_s4, _options$embeddings_s5, _options$embeddings_s6, _options$embeddings_s7, _options$embeddings_s8, _options$embeddings_s9;
const [options, setOptions] = useState(_app_settings__WEBPACK_IMPORTED_MODULE_0__.options);
const baseUrl = _app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl.replace('/wp-json', '');
const [settingsSection, setSettingsSection] = useState(() => {
// Try to restore from localStorage
const saved = localStorage.getItem('mwai_settings_section');
// Validate that the saved section is still valid
if (saved) {
if (saved === 'ai' || saved === 'files' || saved === 'remote' || saved === 'others') {
return saved;
}
// Module-specific sections need to be checked when options are loaded
return saved;
}
return 'ai';
});
const [error, setError] = useState(null);
const [busyAction, setBusyAction] = useState(false);
const [busyEmbeddingsSearch, setBusyEmbeddingsSearch] = useState(false);
const module_suggestions = options === null || options === void 0 ? void 0 : options.module_suggestions;
const module_advisor = options === null || options === void 0 ? void 0 : options.module_advisor;
const module_forms = options === null || options === void 0 ? void 0 : options.module_forms;
const module_finetunes = options === null || options === void 0 ? void 0 : options.module_finetunes;
const module_statistics = options === null || options === void 0 ? void 0 : options.module_statistics;
const module_playground = options === null || options === void 0 ? void 0 : options.module_playground;
const module_generator_content = options === null || options === void 0 ? void 0 : options.module_generator_content;
const module_generator_images = options === null || options === void 0 ? void 0 : options.module_generator_images;
const module_moderation = options === null || options === void 0 ? void 0 : options.module_moderation;
const module_embeddings = options === null || options === void 0 ? void 0 : options.module_embeddings;
const module_assistants = options === null || options === void 0 ? void 0 : options.module_assistants;
const module_transcription = options === null || options === void 0 ? void 0 : options.module_transcription;
const module_addons = options === null || options === void 0 ? void 0 : options.module_addons;
const module_devtools = options === null || options === void 0 ? void 0 : options.module_devtools;
const module_chatbots = options === null || options === void 0 ? void 0 : options.module_chatbots;
const module_search = options === null || options === void 0 ? void 0 : options.module_search;
const module_orchestration = options === null || options === void 0 ? void 0 : options.module_orchestration;
const ai_envs = useMemo(() => options !== null && options !== void 0 && options.ai_envs ? options === null || options === void 0 ? void 0 : options.ai_envs : [], [options]);
const mcp_envs = useMemo(() => options !== null && options !== void 0 && options.mcp_envs ? options === null || options === void 0 ? void 0 : options.mcp_envs : [], [options]);
const ai_fast_default_env = options === null || options === void 0 ? void 0 : options.ai_fast_default_env;
const ai_fast_default_model = options === null || options === void 0 ? void 0 : options.ai_fast_default_model;
const ai_default_env = options === null || options === void 0 ? void 0 : options.ai_default_env;
const ai_default_model = options === null || options === void 0 ? void 0 : options.ai_default_model;
const ai_vision_default_env = options === null || options === void 0 ? void 0 : options.ai_vision_default_env;
const ai_vision_default_model = options === null || options === void 0 ? void 0 : options.ai_vision_default_model;
const ai_embeddings_default_env = options === null || options === void 0 ? void 0 : options.ai_embeddings_default_env;
const ai_embeddings_default_model = options === null || options === void 0 ? void 0 : options.ai_embeddings_default_model;
const ai_images_default_env = options === null || options === void 0 ? void 0 : options.ai_images_default_env;
const ai_images_default_model = options === null || options === void 0 ? void 0 : options.ai_images_default_model;
const ai_audio_default_env = options === null || options === void 0 ? void 0 : options.ai_audio_default_env;
const ai_audio_default_model = options === null || options === void 0 ? void 0 : options.ai_audio_default_model;
const ai_json_default_env = options === null || options === void 0 ? void 0 : options.ai_json_default_env;
const ai_json_default_model = options === null || options === void 0 ? void 0 : options.ai_json_default_model;
const ai_streaming = options === null || options === void 0 ? void 0 : options.ai_streaming;
const ai_responses_api = options === null || options === void 0 ? void 0 : options.ai_responses_api;
const privacy_first = options === null || options === void 0 ? void 0 : options.privacy_first;
const embeddings_envs = options !== null && options !== void 0 && options.embeddings_envs ? options === null || options === void 0 ? void 0 : options.embeddings_envs : [];
const embeddings_default_env = options === null || options === void 0 ? void 0 : options.embeddings_default_env;
const syntax_highlight = options === null || options === void 0 ? void 0 : options.syntax_highlight;
const event_logs = options === null || options === void 0 ? void 0 : options.event_logs;
const chatbot_discussions = options === null || options === void 0 ? void 0 : options.chatbot_discussions;
const virtual_keyboard_fix = options === null || options === void 0 ? void 0 : options.virtual_keyboard_fix;
const chatbot_gdpr_consent = options === null || options === void 0 ? void 0 : options.chatbot_gdpr_consent;
const chatbot_gdpr_text = options === null || options === void 0 ? void 0 : options.chatbot_gdpr_text;
const chatbot_gdpr_button = options === null || options === void 0 ? void 0 : options.chatbot_gdpr_button;
const speech_recognition = options === null || options === void 0 ? void 0 : options.speech_recognition;
const speech_synthesis = options === null || options === void 0 ? void 0 : options.speech_synthesis;
const public_api = options === null || options === void 0 ? void 0 : options.public_api;
const statistics_data = options === null || options === void 0 ? void 0 : options.statistics_data;
const statistics_forms_data = options === null || options === void 0 ? void 0 : options.statistics_forms_data;
const intro_message = options === null || options === void 0 ? void 0 : options.intro_message;
const addons = options === null || options === void 0 ? void 0 : options.module_addons;
const context_max_length = options === null || options === void 0 ? void 0 : options.context_max_length;
const banned_ips = options === null || options === void 0 ? void 0 : options.banned_ips;
const banned_words = options === null || options === void 0 ? void 0 : options.banned_words;
const ignore_word_boundaries = options === null || options === void 0 ? void 0 : options.ignore_word_boundaries;
const custom_languages = (options === null || options === void 0 ? void 0 : options.custom_languages) || [];
const admin_bar = (options === null || options === void 0 ? void 0 : options.admin_bar) ?? ['settings'];
const resolve_shortcodes = options === null || options === void 0 ? void 0 : options.resolve_shortcodes;
const clean_uninstall = options === null || options === void 0 ? void 0 : options.clean_uninstall;
const {
completionModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options);
const {
visionModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options, options === null || options === void 0 ? void 0 : options.ai_vision_default_env);
const {
audioModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options, options === null || options === void 0 ? void 0 : options.ai_audio_default_env);
const {
jsonModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options, options === null || options === void 0 ? void 0 : options.ai_json_default_env);
const {
imageModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options, options === null || options === void 0 ? void 0 : options.ai_images_default_env);
const {
embeddingsModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.useModels)(options, options === null || options === void 0 ? void 0 : options.ai_embeddings_default_env);
// Filter AI environments to only show those with embedding models
const ai_envs_with_embeddings = useMemo(() => {
if (!ai_envs || !(options !== null && options !== void 0 && options.ai_engines)) return [];
return ai_envs.filter(aiEnv => {
// Find the engine that matches this environment's type
const engine = options.ai_engines.find(eng => eng.type === aiEnv.type);
if (!engine || !engine.models) return false;
// Check if any models in this engine have the embedding tag
const hasEmbeddingModels = engine.models.some(model => {
var _model$tags;
return model === null || model === void 0 || (_model$tags = model.tags) === null || _model$tags === void 0 ? void 0 : _model$tags.includes('embedding');
});
return hasEmbeddingModels;
});
}, [ai_envs, options]);
const defaultEmbeddingsModel = useMemo(() => {
return embeddingsModels.find(x => x.model === ai_embeddings_default_model);
}, [embeddingsModels, ai_embeddings_default_model]);
// Generate dimension options for embeddings models
const embeddingsDimensionOptions = useMemo(() => {
var _defaultEmbeddingsMod, _defaultEmbeddingsMod2;
if (!defaultEmbeddingsModel) return [];
// Check if the model supports matryoshka (dimension truncation)
const isMatryoshka = defaultEmbeddingsModel === null || defaultEmbeddingsModel === void 0 || (_defaultEmbeddingsMod = defaultEmbeddingsModel.tags) === null || _defaultEmbeddingsMod === void 0 ? void 0 : _defaultEmbeddingsMod.includes('matryoshka');
if (isMatryoshka && (defaultEmbeddingsModel === null || defaultEmbeddingsModel === void 0 || (_defaultEmbeddingsMod2 = defaultEmbeddingsModel.dimensions) === null || _defaultEmbeddingsMod2 === void 0 ? void 0 : _defaultEmbeddingsMod2.length) > 0) {
const maxDimension = defaultEmbeddingsModel.dimensions[0];
// Common matryoshka dimensions in descending order
const matryoshkaDimensions = [3072, 2048, 1536, 1024, 768, 512];
// Filter dimensions that are <= the model's max dimension
return matryoshkaDimensions.filter(dim => dim <= maxDimension);
}
// For non-matryoshka models, return the original dimensions
return (defaultEmbeddingsModel === null || defaultEmbeddingsModel === void 0 ? void 0 : defaultEmbeddingsModel.dimensions) || [];
}, [defaultEmbeddingsModel]);
const busy = busyAction;
const updateOptions = useCallback(async newOptions => {
try {
if ((0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoStringify)(newOptions) === (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoStringify)(options)) {
return;
}
setBusyAction(true);
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/update`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce,
json: {
options: newOptions
}
});
setOptions(response.options);
} catch (err) {
console.error(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ERROR.UPDATING_OPTIONS, err !== null && err !== void 0 && err.message ? {
message: err.message,
options,
newOptions
} : {
err,
options,
newOptions
});
if (err.message) {
setError( /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ERROR.UPDATING_OPTIONS), /*#__PURE__*/React.createElement("small", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ERROR.CHECK_YOUR_CONSOLE))));
}
} finally {
setBusyAction(false);
}
}, [options]);
useEffect(() => {
const performChecks = async () => {
let updatesNeeded = false;
const newOptions = {
...options
};
defaultEnvironmentSections.forEach(({
envKey,
modelKey,
defaultModel
}) => {
let exists = false;
if (options[envKey]) {
exists = !!ai_envs.find(x => x.id === options[envKey]);
}
if (!exists) {
const foundEnv = ai_envs.find(x => (x === null || x === void 0 ? void 0 : x.type) === 'openai');
if (foundEnv) {
if (newOptions[envKey] !== foundEnv.id || newOptions[modelKey] !== defaultModel) {
console.warn(`Updating ${envKey} and ${modelKey} to ${foundEnv.id} and ${defaultModel}`);
updatesNeeded = true;
newOptions[envKey] = foundEnv.id;
newOptions[modelKey] = defaultModel;
}
} else {
if (newOptions[envKey] !== null || newOptions[modelKey] !== null) {
console.warn(`Updating ${envKey} and ${modelKey} to null`);
updatesNeeded = true;
newOptions[envKey] = null;
newOptions[modelKey] = null;
}
}
}
// We need to make sure the dimensions are valid
if (modelKey === 'ai_embeddings_default_model' && newOptions[modelKey]) {
const dimensions = (newOptions === null || newOptions === void 0 ? void 0 : newOptions.ai_embeddings_default_dimensions) || null;
if (dimensions !== null) {
const model = embeddingsModels.find(x => x.model === newOptions[modelKey]);
if (model) {
var _model$tags2, _model$dimensions;
// Check if the model supports matryoshka
const isMatryoshka = model === null || model === void 0 || (_model$tags2 = model.tags) === null || _model$tags2 === void 0 ? void 0 : _model$tags2.includes('matryoshka');
let validDimensions = (model === null || model === void 0 ? void 0 : model.dimensions) || [];
if (isMatryoshka && (model === null || model === void 0 || (_model$dimensions = model.dimensions) === null || _model$dimensions === void 0 ? void 0 : _model$dimensions.length) > 0) {
const maxDimension = model.dimensions[0];
const matryoshkaDimensions = [3072, 2048, 1536, 1024, 768, 512];
validDimensions = matryoshkaDimensions.filter(dim => dim <= maxDimension);
}
// Check if current dimension is valid
if (!validDimensions.includes(parseInt(dimensions))) {
const newDimensions = validDimensions[0] || null;
if (newDimensions !== null) {
newOptions.ai_embeddings_default_dimensions = newDimensions;
console.warn(`Updating embeddings default dimensions to ${newDimensions}`);
updatesNeeded = true;
}
}
}
}
}
});
if (updatesNeeded) {
await updateOptions(newOptions);
}
};
performChecks();
}, [ai_envs, options, updateOptions, embeddingsModels]);
const refreshOptions = async () => {
setBusyAction(true);
try {
const options = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.retrieveOptions)();
setOptions(options);
} catch (err) {
console.error(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ERROR.GETTING_OPTIONS, err !== null && err !== void 0 && err.message ? {
message: err.message
} : {
err
});
if (err.message) {
setError( /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ERROR.GETTING_OPTIONS), /*#__PURE__*/React.createElement("small", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ERROR.CHECK_YOUR_CONSOLE))));
}
} finally {
setBusyAction(false);
}
};
const updateOption = async (value, id) => {
const newOptions = {
...options,
[id]: value
};
await updateOptions(newOptions);
};
const updateEmbeddingsSearchOption = async value => {
setBusyEmbeddingsSearch(true);
try {
await updateOption(value, 'embeddings_settings');
} finally {
setBusyEmbeddingsSearch(false);
}
};
const updateVectorDbEnvironment = async (id, updatedValue) => {
const updatedEnvironments = embeddings_envs.map(env => {
if (env.id === id) {
return {
...env,
...updatedValue
};
}
return env;
});
updateOption(updatedEnvironments, 'embeddings_envs');
};
const updateAIEnvironment = async (id, updatedValue) => {
const updatedEnvironments = ai_envs.map(env => {
if (env.id === id) {
return {
...env,
...updatedValue
};
}
return env;
});
updateOption(updatedEnvironments, 'ai_envs');
};
const updateMCPServer = async (id, updatedValue) => {
const updatedServers = mcp_envs.map(server => {
if (server.id === id) {
return {
...server,
...updatedValue
};
}
return server;
});
updateOption(updatedServers, 'mcp_envs');
};
const onResetSettings = async () => {
if (!window.confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].ALERTS.ARE_YOU_SURE)) {
return;
}
setBusyAction(true);
try {
await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/reset`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce
});
alert("Settings reset. The page will now reload to reflect the changes.");
window.location.reload();
} catch (err) {
alert("Error while resetting settings. Please check your console.");
console.log(err);
} finally {
setBusyAction(false);
}
};
// Will export as a file with a JSON { themes, chatbots, options }
// No need to load, we already have the data
const onExportSettings = async () => {
setBusyAction('exportSettings');
try {
const chatbots = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.retrieveChatbots)();
const themes = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.retrieveThemes)();
const options = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.retrieveOptions)();
const data = {
chatbots,
themes,
options
};
const blob = new Blob([(0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoStringify)(data)], {
type: 'application/json'
});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
const today = new Date();
const filename = `ai-engine-${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}.json`;
link.setAttribute('download', filename);
link.click();
} catch (err) {
alert("Error while exporting settings. Please check your console.");
console.log(err);
} finally {
setBusyAction(false);
}
};
// This will ask for a file to import, and then update the settings
const onImportSettings = async () => {
setBusyAction('importSettings');
try {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'application/json';
fileInput.onchange = async e => {
const file = e.target.files[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = async e => {
const data = JSON.parse(e.target.result);
const {
chatbots,
themes,
options
} = data;
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.updateChatbots)(chatbots);
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.updateThemes)(themes);
await updateOptions(options);
alert("Settings imported. The page will now reload to reflect the changes.");
window.location.reload();
};
reader.readAsText(file);
};
fileInput.click();
} catch (err) {
alert("Error while importing settings. Please check your console.");
console.log(err);
} finally {
setBusyAction(false);
}
};
// Reset some options when the user is not registered.
useEffect(() => {
if (!_app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered) {
const newOptions = {
...options
};
let hasChanges = false;
proOptions.forEach(option => {
if (newOptions[option]) {
newOptions[option] = false;
console.warn(`Resetting ${option}`);
hasChanges = true;
}
});
if (hasChanges) {
if ((0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoStringify)(newOptions) !== (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoStringify)(options)) {
updateOptions(newOptions);
}
}
}
}, []);
// Save settings section to localStorage whenever it changes
useEffect(() => {
localStorage.setItem('mwai_settings_section', settingsSection);
}, [settingsSection]);
// Automatically disable Event Logs when Streaming is turned off
useEffect(() => {
if (!ai_streaming && event_logs) {
updateOption(false, 'event_logs');
}
}, [ai_streaming, event_logs, updateOption]);
// Validate saved section when modules change
useEffect(() => {
const isValidSection = () => {
if (settingsSection === 'ai' || settingsSection === 'files' || settingsSection === 'remote' || settingsSection === 'others') {
return true;
}
if (settingsSection === 'chatbot' && module_chatbots) return true;
if (settingsSection === 'knowledge' && module_embeddings) return true;
if (settingsSection === 'orchestration' && module_orchestration) return true;
return false;
};
if (!isValidSection()) {
setSettingsSection('ai');
}
}, [settingsSection, module_chatbots, module_embeddings, module_orchestration]);
const jsxUtilities = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.UTILITIES
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_suggestions",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.POSTS_SUGGESTIONS,
value: "1",
checked: module_suggestions,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.POSTS_SUGGESTIONS_HELP,
onChange: updateOption
})));
const jsxAdvisors = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ADVISOR
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_advisor",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_advisor,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.ADVISOR,
onChange: updateOption
})));
const jsxGenerators = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GENERATORS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_generator_content",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CONTENT_GENERATOR,
value: "1",
checked: module_generator_content,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CONTENT_GENERATOR_HELP,
onChange: updateOption
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_generator_images",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.IMAGES_GENERATOR,
value: "1",
checked: module_generator_images,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.IMAGES_GENERATOR_HELP,
onChange: updateOption
})));
const jsxPlayground = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PLAYGROUND
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_playground",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_playground,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PLAYGROUND_HELP,
onChange: updateOption
}));
const jsxForms = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.FORMS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_forms",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_forms,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.FORMS_HELP,
onChange: updateOption
}));
const jsxSearch = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SEARCH
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_search",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_search,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SEARCH_HELP,
onChange: updateOption
}));
const jsxFinetunes = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.FINETUNES
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_finetunes",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_finetunes,
description: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.OpenAiIcon, {
disabled: !module_finetunes,
style: {
marginRight: 3
}
}), _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.FINETUNES),
onChange: updateOption
}));
const jsxInsights = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: /*#__PURE__*/React.createElement(React.Fragment, null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.INSIGHTS)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_statistics",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_statistics,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.INSIGHTS_HELP,
onChange: updateOption
}));
const jsxModeration = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: /*#__PURE__*/React.createElement(React.Fragment, null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODERATION)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_moderation",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_moderation,
description: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.OpenAiIcon, {
disabled: !module_moderation,
style: {
marginRight: 3
}
}), _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODERATION_HELP),
onChange: updateOption
}));
const jsxTranscribe = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: /*#__PURE__*/React.createElement(React.Fragment, null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.TRANSCRIPTION)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_transcription",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_transcription,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.TRANSCRIPTION_HELP,
onChange: updateOption
}));
const jsxKnowledge = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: /*#__PURE__*/React.createElement(React.Fragment, null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.KNOWLEDGE)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_embeddings",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_embeddings,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.KNOWLEDGE_HELP),
onChange: updateOption
}));
const jsxAssistants = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: /*#__PURE__*/React.createElement(React.Fragment, null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ASSISTANTS, /*#__PURE__*/React.createElement("small", {
style: {
position: 'relative',
top: -3,
fontSize: 8
}
}, " BETA"))
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_assistants",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_assistants,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.OpenAiIcon, {
disabled: !module_assistants,
style: {
marginRight: 3
}
}), _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.ASSISTANTS),
onChange: updateOption
}));
const jsxOrchestration = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ORCHESTRATION
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_orchestration",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_orchestration,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ORCHESTRATION_HELP,
onChange: updateOption
}));
const jsxChatbot = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_chatbots",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_chatbots,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT_HELP,
onChange: updateOption
})));
const jsxStatisticsData = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.QUERIES_DATA
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "statistics_data",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: statistics_data,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.QUERIES_DATA,
onChange: updateOption
})));
const jsxStatisticsFormsData = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.QUERIES_FORMS_DATA
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "statistics_forms_data",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: statistics_forms_data,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.QUERIES_FORMS_DATA,
onChange: updateOption
})));
const jsxIntroMessage = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.INTRO_MESSAGE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "intro_message",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: intro_message,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.INTRO_MESSAGE,
onChange: updateOption
})));
const jsxAddOns = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ADDONS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_addons",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: addons,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.ADDONS,
onChange: updateOption
})));
const jsxChatbotSelection = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT_SELECT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "chatbot_select",
value: options === null || options === void 0 ? void 0 : options.chatbot_select,
onChange: updateOption,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.CHATBOT_SELECT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "tabs",
value: "tabs",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.TABS
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "dropdown",
value: "dropdown",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DROPDOWN
})));
const jsxWebSpeechAPI = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.WEBSPEECH_API
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "speech_recognition",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SPEECH_RECOGNITION,
value: "1",
checked: speech_recognition,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.SPEECH_RECOGNITION,
onChange: updateOption
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "speech_synthesis",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SPEECH_SYNTHESIS + " (SOON)",
value: "1",
disabled: true,
checked: speech_synthesis,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.SPEECH_SYNTHESIS,
onChange: updateOption
})));
const jsxVirtualKeyboardFix = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.VIRTUAL_KEYBOARD
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "virtual_keyboard_fix",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.FIX,
value: "1",
checked: virtual_keyboard_fix,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.VIRTUAL_KEYBOARD,
onChange: updateOption
})));
const jsxChatbotGDPRConsent = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GDPR_CONSENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_gdpr_consent",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: chatbot_gdpr_consent,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.GDPR_CONSENT,
onChange: updateOption
})));
const jsxChatbotGDPRMessage = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GDPR_TEXT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
name: "chatbot_gdpr_text",
value: chatbot_gdpr_text,
onBlur: updateOption
}));
const jsxChatbotGDPRButton = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GDPR_BUTTON
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
name: "chatbot_gdpr_button",
value: chatbot_gdpr_button,
onBlur: updateOption
}));
const jsxStream = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.STREAMING
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "ai_streaming",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: ai_streaming,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.STREAMING,
onChange: updateOption
})));
const jsxResponsesApi = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Responses API"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "ai_responses_api",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: ai_responses_api,
description: "Use OpenAI's new Responses API for improved performance and features. This is recommended, but can be disabled if you experience issues.",
onChange: updateOption
})));
const jsxPrivacyFirst = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PRIVACY_FIRST
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "privacy_first",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: privacy_first,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.PRIVACY_FIRST,
onChange: updateOption
})));
// const jsxShortcodeTypewriter =
// <NekoSettings title={i18n.SETTINGS.TYPEWRITER_EFFECT}>
// <NekoCheckboxGroup max="1">
// <NekoCheckbox name="chatbot_typewriter" label={i18n.COMMON.ENABLE} value="1"
// checked={chatbot_typewriter}
// description={toHTML(i18n.SETTINGS.TYPEWRITER_EFFECT_HELP)}
// onChange={updateOption} />
// </NekoCheckboxGroup>
// </NekoSettings>;
const jsxShortcodeDiscussions = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DISCUSSIONS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_discussions",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: chatbot_discussions,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.DISCUSSIONS,
onChange: updateOption
})));
const jsxDiscussionSummary = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SUMMARIZE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_discussions_titling",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.chatbot_discussions_titling,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.DISCUSSION_SUMMARY,
onChange: updateOption
})));
const jsxDiscussionsPaging = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PAGING || 'Paging'
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "chatbot_discussions_paging",
value: (options === null || options === void 0 ? void 0 : options.chatbot_discussions_paging) || 10,
onChange: updateOption,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.DISCUSSIONS_PAGING || 'Number of discussions to display per page'
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "None",
label: "None"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 5,
label: "5 per Page"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 10,
label: "10 per Page"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 15,
label: "15 per Page"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 20,
label: "20 per Page"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 30,
label: "30 per Page"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 50,
label: "50 per Page"
})));
const jsxDiscussionsRefreshInterval = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.REFRESH_INTERVAL || 'Refresh Interval'
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "chatbot_discussions_refresh_interval",
value: (options === null || options === void 0 ? void 0 : options.chatbot_discussions_refresh_interval) || 5,
onChange: updateOption,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.DISCUSSIONS_REFRESH_INTERVAL || 'How often to refresh the discussions list (in seconds)'
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 1,
label: "1 second"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 2,
label: "2 seconds"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 5,
label: "5 seconds"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 10,
label: "10 seconds"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 30,
label: "30 seconds"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 60,
label: "60 seconds"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: 120,
label: "120 seconds"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "Manual",
label: "Manually"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "Never",
label: "Never"
})));
const jsxDiscussionsMetadata = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Metadata Bar"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_discussions_metadata_enabled",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.chatbot_discussions_metadata_enabled,
description: "Display a metadata bar under discussion titles.",
onChange: updateOption
})));
const jsxDiscussionsMetadataOptions = options !== null && options !== void 0 && options.chatbot_discussions_metadata_enabled ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Metadata Display"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "3"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_discussions_metadata_start_date",
label: "Start Date",
value: "1",
checked: options === null || options === void 0 ? void 0 : options.chatbot_discussions_metadata_start_date,
description: "Show when the discussion was created.",
onChange: updateOption
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_discussions_metadata_last_update",
label: "Last Update",
value: "1",
checked: options === null || options === void 0 ? void 0 : options.chatbot_discussions_metadata_last_update,
description: "Show when the discussion was last modified.",
onChange: updateOption
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "chatbot_discussions_metadata_message_count",
label: "Message Count",
value: "1",
checked: options === null || options === void 0 ? void 0 : options.chatbot_discussions_metadata_message_count,
description: "Show the number of messages in the discussion.",
onChange: updateOption
}))) : null;
const jsxShortcodeSyntaxHighlighting = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SYNTAX_HIGHLIGHT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "syntax_highlight",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: syntax_highlight,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.SYNTAX_HIGHLIGHT,
onChange: updateOption
})));
const jsxEventLogs = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.EVENT_LOGS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "event_logs",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: event_logs,
disabled: !ai_streaming,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.EVENT_LOGS,
onChange: updateOption
})));
const jsxPublicAPI = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PUBLIC_API
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "public_api",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: public_api,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.PUBLIC_API,
onChange: updateOption
}), public_api && /*#__PURE__*/React.createElement(_app_components_CopyableField__WEBPACK_IMPORTED_MODULE_10__["default"], {
value: `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/mwai/v1/`
}, /*#__PURE__*/React.createElement("span", null, baseUrl, /*#__PURE__*/React.createElement("span", {
className: "highlight"
}, "/wp-json/mwai/v1/"))));
const jsxBearerToken = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.BEARER_TOKEN
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
name: "public_api_bearer_token",
value: options === null || options === void 0 ? void 0 : options.public_api_bearer_token,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.BEARER_TOKEN),
onBlur: updateOption
}));
const jsxMcpModule = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "SSE Endpoint"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_mcp",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.module_mcp,
description: "Enable the /wp-json/mcp/v1/sse endpoint. Check the labs/mcp.md for more information.",
onChange: updateOption
}), (options === null || options === void 0 ? void 0 : options.module_mcp) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_components_CopyableField__WEBPACK_IMPORTED_MODULE_10__["default"], {
value: `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/mcp/v1/sse`
}, /*#__PURE__*/React.createElement("span", null, baseUrl, /*#__PURE__*/React.createElement("span", {
className: "highlight"
}, "/wp-json/mcp/v1/sse")))));
const jsxMcpBearerToken = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.BEARER_TOKEN
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
name: "mcp_bearer_token",
value: options === null || options === void 0 ? void 0 : options.mcp_bearer_token,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.MCP_BEARER_TOKEN),
onBlur: updateOption
}));
const jsxMcpNoAuthUrl = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "No-Auth URL"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "mcp_noauth_url",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.mcp_noauth_url,
disabled: !(options !== null && options !== void 0 && options.module_mcp) || !(options !== null && options !== void 0 && options.mcp_bearer_token),
description: "Enable a special URL that includes authentication in the path. Only works when SSE Endpoint is enabled and Bearer Token is set.",
onChange: updateOption
}), (options === null || options === void 0 ? void 0 : options.mcp_noauth_url) && (options === null || options === void 0 ? void 0 : options.module_mcp) && (options === null || options === void 0 ? void 0 : options.mcp_bearer_token) && /*#__PURE__*/React.createElement(_app_components_CopyableField__WEBPACK_IMPORTED_MODULE_10__["default"], {
value: `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/mcp/v1/${options.mcp_bearer_token}/sse`
}, /*#__PURE__*/React.createElement("span", null, baseUrl, "/wp-json/mcp/v1/", /*#__PURE__*/React.createElement("span", {
className: "highlight"
}, options.mcp_bearer_token), "/sse")));
const jsxMcpCore = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Tuned Core"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "mcp_core",
label: "Enable (Recommended)",
value: "1",
checked: options === null || options === void 0 ? void 0 : options.mcp_core,
description: "A highly-optimized MCP integration providing a streamlined, AI-focused layer tailored specifically for ease-of-use, performance, and clarity.",
onChange: updateOption
}));
const jsxMcpPlugins = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Tuned Plugins"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "mcp_plugins",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.mcp_plugins,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: "Create, fork, edit, and manage plugins directly through MCP.",
onChange: updateOption
}));
const jsxMcpThemes = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Tuned Themes"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "mcp_themes",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.mcp_themes,
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered,
description: "Enables theme management, editing, and the ability to fork existing themes into new ones to effortlessly integrate additional features.",
onChange: updateOption
}));
const jsxMcpDynamicRest = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Dynamic REST"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "mcp_dynamic_rest",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: options === null || options === void 0 ? void 0 : options.mcp_dynamic_rest,
description: "The Automattic way. Dynamically provide comprehensive access to WordPress's REST API endpoints through MCP. Might be more obscure for the AI to work with.",
onChange: updateOption
}));
const jsxImageLocalUpload = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Local Upload"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "image_local_upload",
value: options === null || options === void 0 ? void 0 : options.image_local_upload,
onChange: updateOption,
description: "Files can be stored either in the filesystem or the Media Library."
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "uploads",
value: "uploads",
label: "Filesystem"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "library",
value: "library",
label: "Media Library"
})));
const jsxImageRemoteUpload = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Remote Upload"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "image_remote_upload",
value: options === null || options === void 0 ? void 0 : options.image_remote_upload,
onChange: updateOption,
description: "Select Upload Data for private sites; Share URLs requires your WordPress to be online and reachable."
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "data",
value: "data",
label: "Upload Data"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "url",
value: "url",
label: "Share URLs"
})));
const jsxImageExpiration = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Expiration"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "image_expires",
value: (options === null || options === void 0 ? void 0 : options.image_expires) ?? 'never',
onChange: updateOption,
description: "Uploaded files will be deleted after a certain amount of time. This also affects files uploaded to OpenAI via the Assistants."
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 5 * 60,
value: 5 * 60,
label: "5 minutes"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 1 * 60 * 60,
value: 1 * 60 * 60,
label: "1 hour"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 6 * 60 * 60,
value: 6 * 60 * 60,
label: "6 hours"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 24 * 60 * 60,
value: 24 * 60 * 60,
label: "1 day"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 7 * 24 * 60 * 60,
value: 7 * 24 * 60 * 60,
label: "1 week"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 30 * 24 * 60 * 60,
value: 30 * 24 * 60 * 60,
label: "1 month"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 'Never',
value: 'never',
label: "Never"
})));
const jsxImageLocalDownload = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Local Download"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "image_local_download",
value: (options === null || options === void 0 ? void 0 : options.image_local_download) ?? null,
onChange: updateOption,
description: "Files can be stored either in the filesystem or the Media Library."
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: null,
value: null,
label: "None"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "uploads",
value: "uploads",
label: "Filesystem"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: "library",
value: "library",
label: "Media Library"
})));
const jsxImageExpirationDownload = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Expiration"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "image_expires_download",
value: (options === null || options === void 0 ? void 0 : options.image_expires_download) ?? 'never',
onChange: updateOption,
description: "Downloaded files will be deleted after a certain amount of time."
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 5 * 60,
value: 5 * 60,
label: "5 minutes"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 1 * 60 * 60,
value: 1 * 60 * 60,
label: "1 hour"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 6 * 60 * 60,
value: 6 * 60 * 60,
label: "6 hours"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 24 * 60 * 60,
value: 24 * 60 * 60,
label: "1 day"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 7 * 24 * 60 * 60,
value: 7 * 24 * 60 * 60,
label: "1 week"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 30 * 24 * 60 * 60,
value: 30 * 24 * 60 * 60,
label: "1 month"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: 'Never',
value: 'never',
label: "Never"
})));
const jsxDevTools = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DEV_TOOLS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "module_devtools",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: module_devtools,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.DEV_TOOLS,
onChange: updateOption
}));
const jsxResolveShortcodes = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SHORTCODES
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "resolve_shortcodes",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.RESOLVE,
value: "1",
checked: resolve_shortcodes,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.RESOLVE_SHORTCODE,
onChange: updateOption
}));
const jsxContextMaxTokens = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CONTEXT_MAX_LENGTH
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
name: "context_max_length",
value: context_max_length,
type: "number",
step: "1",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.CONTEXT_MAX_LENGTH,
onBlur: updateOption
}));
const jsxBannedKeywords = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.BANNED_WORDS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
id: "banned_words",
name: "banned_words",
value: banned_words,
isCommaSeparatedArray: true,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.BANNED_WORDS,
onBlur: updateOption
}));
const jsxIgnoreWordBoundaries = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.WORD_BOUNDARIES
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "ignore_word_boundaries",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.IGNORE,
value: "1",
checked: ignore_word_boundaries,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.WORD_BOUNDARIES,
onChange: updateOption
})));
const jsxAIEnvironmentModelDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_default_model",
value: ai_default_model,
onChange: updateOption
}, completionModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxAIEnvironmentModelFastDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_fast_default_model",
value: ai_fast_default_model,
onChange: updateOption
}, completionModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxAIEnvironmentModelEmbeddingsDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_embeddings_default_model",
value: ai_embeddings_default_model,
onChange: updateOption
}, embeddingsModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxAIEnvironmentDimensionsEmbeddingsDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DIMENSIONS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_embeddings_default_dimensions",
value: options !== null && options !== void 0 && options.ai_embeddings_default_dimensions ? parseInt(options.ai_embeddings_default_dimensions) : null,
onChange: updateOption
}, embeddingsDimensionOptions.map((x, i) => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x,
value: x,
label: i === 0 ? `${x} (Native)` : x
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: null,
value: null,
label: "Not Set"
})));
const jsxAIEnvironmentModelVisionDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_vision_default_model",
value: ai_vision_default_model,
onChange: updateOption
}, visionModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxAIEnvironmentModelAudioDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_audio_default_model",
value: ai_audio_default_model,
onChange: updateOption
}, audioModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxAIEnvironmentModelJsonDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_json_default_model",
value: ai_json_default_model,
onChange: updateOption
}, jsonModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxAIEnvironmentModelImagesDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_images_default_model",
value: ai_images_default_model,
onChange: updateOption
}, imageModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))));
const jsxBannedIPs = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.BANNED_IPS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
id: "banned_ips",
name: "banned_ips",
value: banned_ips,
isCommaSeparatedArray: true,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.BANNED_IPS,
onBlur: updateOption
}));
const jsxCustomLanguages = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Available Languages"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
id: "custom_languages",
name: "custom_languages",
value: custom_languages,
isCommaSeparatedArray: true,
description: "The complete list of languages available in AI Engine. You can add, remove, or modify languages. Use format: 'Language Name (code)' or just 'Language Name'. The language code (e.g., 'en', 'fr') helps with internationalization but is optional.",
placeholder: "English (en), French (fr), Spanish (es), German (de)",
onBlur: updateOption
}));
const jsxAdminBarPlayground = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PLAYGROUND
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: admin_bar === null || admin_bar === void 0 ? void 0 : admin_bar.playground,
onChange: value => {
const freshAdminBar = {
...admin_bar,
playground: value
};
updateOption(freshAdminBar, 'admin_bar');
}
}));
const jsxAdminBarGenerateContent = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GENERATE_CONTENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: admin_bar === null || admin_bar === void 0 ? void 0 : admin_bar.content_generator,
onChange: value => {
const freshAdminBar = {
...admin_bar,
content_generator: value
};
updateOption(freshAdminBar, 'admin_bar');
}
}));
const jsxAdminBarGenerateImages = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GENERATE_IMAGES
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: admin_bar === null || admin_bar === void 0 ? void 0 : admin_bar.images_generator,
onChange: value => {
const freshAdminBar = {
...admin_bar,
images_generator: value
};
updateOption(freshAdminBar, 'admin_bar');
}
}));
const jsxAdminBarSettings = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: 'AI Engine'
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: admin_bar === null || admin_bar === void 0 ? void 0 : admin_bar.settings,
onChange: value => {
const freshAdminBar = {
...admin_bar,
settings: value
};
updateOption(freshAdminBar, 'admin_bar');
}
}));
const jsxUsage = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_app_components_UsageWidget__WEBPACK_IMPORTED_MODULE_11__["default"], {
options: options
}));
const jsxAIEnvironmentDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_default_env",
value: ai_default_env,
onChange: updateOption
}, ai_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxAIEnvironmentFastDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_fast_default_env",
value: ai_fast_default_env,
onChange: updateOption
}, ai_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxAIEnvironmentEmbeddingsDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_embeddings_default_env",
value: ai_embeddings_default_env,
onChange: updateOption
}, ai_envs_with_embeddings.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxAIEnvironmentVisionDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_vision_default_env",
value: ai_vision_default_env,
onChange: updateOption
}, ai_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxAIEnvironmentAudioDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_audio_default_env",
value: ai_audio_default_env,
onChange: updateOption
}, ai_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxAIEnvironmentJsonDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_json_default_env",
value: ai_json_default_env,
onChange: updateOption
}, ai_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxAIEnvironmentImagesDefault = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "ai_images_default_env",
value: ai_images_default_env,
onChange: updateOption
}, ai_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))));
const jsxKnowledgeEnvironmentDefault = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "embeddings_default_env",
value: embeddings_default_env,
onChange: updateOption
}, embeddings_envs.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})));
const jsxCleanUninstall = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PLUGIN_DATA
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "clean_uninstall",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DELETE_ALL,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.PLUGIN_DATA_DESCRIPTION,
value: "1",
checked: clean_uninstall,
onChange: updateOption
})));
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoPage, null, /*#__PURE__*/React.createElement(_app_styles_CommonStyles__WEBPACK_IMPORTED_MODULE_14__.AiNekoHeader, {
options: options
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
fullWidth: true
}, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_1__.OptionsCheck, {
options: options
}), intro_message && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoContainer, null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].SETTINGS.INTRO)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTabs, {
keepTabOnReload: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "dashboard",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DASHBOARD
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CLIENT_MODULES,
className: "primary"
}, jsxChatbot, jsxForms, jsxSearch), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SERVER_MODULES,
className: "primary"
}, jsxInsights, jsxKnowledge, jsxOrchestration, jsxFinetunes, jsxModeration, jsxAssistants), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.BACKEND_MODULES,
className: "primary"
}, jsxAdvisors, jsxGenerators, jsxPlayground, jsxUtilities, jsxTranscribe)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.USAGE,
className: "primary"
}, jsxUsage)))), module_chatbots && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "chatbots",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOTS
}, /*#__PURE__*/React.createElement(_chatbots_Chatbots__WEBPACK_IMPORTED_MODULE_19__["default"], {
options: options,
updateOption: updateOption,
busy: busy
})), module_search && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "search",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SEARCH
}, /*#__PURE__*/React.createElement(_misc_Search__WEBPACK_IMPORTED_MODULE_20__["default"], {
options: options,
updateOption: updateOption,
busy: busy
})), module_chatbots && chatbot_discussions && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "discussions",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DISCUSSIONS
}, /*#__PURE__*/React.createElement(_app_screens_discussions_Discussions__WEBPACK_IMPORTED_MODULE_21__["default"], null)), module_statistics && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "insights",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.INSIGHTS
}, /*#__PURE__*/React.createElement(_app_screens_queries_Insights__WEBPACK_IMPORTED_MODULE_22__["default"], {
options: options,
updateOption: updateOption,
busy: busy
})), module_embeddings && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "knowledge",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.KNOWLEDGE
}, /*#__PURE__*/React.createElement(_app_screens_embeddings_Embeddings__WEBPACK_IMPORTED_MODULE_23__["default"], {
options: options,
updateEnvironment: updateVectorDbEnvironment,
updateOption: updateOption
})), module_assistants && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "assistants",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ASSISTANTS
}, /*#__PURE__*/React.createElement(_assistants_Assistants__WEBPACK_IMPORTED_MODULE_24__["default"], {
options: options,
updateOption: updateOption,
refreshOptions: refreshOptions
})), module_finetunes && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "finetunes",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.FINETUNES
}, /*#__PURE__*/React.createElement(_app_screens_finetunes_Finetunes__WEBPACK_IMPORTED_MODULE_25__["default"], {
options: options,
updateOption: updateOption,
refreshOptions: refreshOptions
})), module_moderation && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "moderation",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MODERATION
}, /*#__PURE__*/React.createElement(_app_screens_misc_Moderation__WEBPACK_IMPORTED_MODULE_26__["default"], {
options: options,
updateOption: updateOption,
busy: busy
})), module_transcription && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "transcription",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.TRANSCRIPTION
}, /*#__PURE__*/React.createElement(_misc_Transcription__WEBPACK_IMPORTED_MODULE_27__["default"], {
options: options,
updateOption: updateOption
})), module_addons && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "addons",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ADDONS
}, /*#__PURE__*/React.createElement(_Addons__WEBPACK_IMPORTED_MODULE_28__["default"], {
addons: options === null || options === void 0 ? void 0 : options.addons,
updateOption: updateOption
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "settings",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SETTINGS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
minimal: true,
fullWidth: true,
style: {
paddingLeft: 10,
paddingTop: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoQuickLinks, {
inversed: true,
name: "quicklinks",
value: settingsSection,
onChange: setSettingsSection
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: "AI",
value: "ai"
}), module_chatbots && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: "Chatbot",
value: "chatbot"
}), module_embeddings && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: "Knowledge",
value: "knowledge"
}), module_orchestration && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: "Orchestration",
value: "orchestration"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: "Files & Media",
value: "files"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.REMOTE_ACCESS,
value: "remote"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_29__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.OTHERS,
value: "others"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
minimal: true,
fullWidth: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
minimal: true
}, settingsSection === 'ai' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_ai_Environments__WEBPACK_IMPORTED_MODULE_30__["default"], {
busy: busy,
options: options,
environments: ai_envs,
updateEnvironment: updateAIEnvironment,
updateOption: updateOption
}), /*#__PURE__*/React.createElement("div", {
style: {
padding: '0px 10px 15px 10px',
marginTop: 13,
marginBottom: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_31__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 15
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.AI_ENVIRONMENT_DEFAULTS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTabs, {
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "ai",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DEFAULT,
busy: busy
}, jsxAIEnvironmentDefault, jsxAIEnvironmentModelDefault), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "fast",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DEFAULT_FAST,
busy: busy
}, jsxAIEnvironmentFastDefault, jsxAIEnvironmentModelFastDefault), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "vision",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.VISION,
busy: busy
}, jsxAIEnvironmentVisionDefault, jsxAIEnvironmentModelVisionDefault), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "images",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.IMAGES,
busy: busy
}, jsxAIEnvironmentImagesDefault, jsxAIEnvironmentModelImagesDefault), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "embeddings",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.EMBEDDINGS,
busy: busy
}, jsxAIEnvironmentEmbeddingsDefault, jsxAIEnvironmentModelEmbeddingsDefault, jsxAIEnvironmentDimensionsEmbeddingsDefault), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "audio",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.AUDIO,
busy: busy
}, jsxAIEnvironmentAudioDefault, jsxAIEnvironmentModelAudioDefault), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "json",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.JSON,
busy: busy
}, jsxAIEnvironmentJsonDefault, jsxAIEnvironmentModelJsonDefault)))), settingsSection === 'knowledge' && module_embeddings && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_embeddings_Environments__WEBPACK_IMPORTED_MODULE_32__["default"], {
busy: busy,
options: options,
environments: embeddings_envs,
updateEnvironment: updateVectorDbEnvironment,
updateOption: updateOption
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.EMBEDDINGS_ENVIRONMENT_DEFAULT,
className: "primary"
}, jsxKnowledgeEnvironmentDefault)), settingsSection === 'chatbot' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT,
className: "primary"
}, jsxShortcodeDiscussions, jsxShortcodeSyntaxHighlighting, jsxWebSpeechAPI, jsxVirtualKeyboardFix, jsxChatbotGDPRConsent, chatbot_gdpr_consent && /*#__PURE__*/React.createElement(React.Fragment, null, jsxChatbotGDPRMessage, jsxChatbotGDPRButton))), settingsSection === 'orchestration' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_orchestration_MCPServers__WEBPACK_IMPORTED_MODULE_33__["default"], {
busy: busy,
options: options,
mcpServers: mcp_envs,
updateMCPServer: updateMCPServer,
updateOption: updateOption
})), settingsSection === 'files' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: "Uploaded by Users",
className: "primary"
}, jsxImageLocalUpload, jsxImageRemoteUpload, jsxImageExpiration), settingsSection === 'others' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.USER_INTERFACE,
className: "primary"
}, jsxIntroMessage, jsxAddOns), settingsSection === 'others' && module_statistics && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.INSIGHTS,
className: "primary"
}, /*#__PURE__*/React.createElement("p", null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.STATISTICS), jsxStatisticsData, jsxStatisticsFormsData), settingsSection === 'others' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ADMIN_BAR,
className: "primary"
}, jsxAdminBarSettings, jsxAdminBarPlayground, jsxAdminBarGenerateContent, jsxAdminBarGenerateImages), settingsSection === 'others' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.MAINTENANCE,
className: "primary"
}, /*#__PURE__*/React.createElement("p", {
style: {
marginBottom: '15px'
}
}, "It is important to keep regular backups of your settings. Use Export Settings to save your configuration. Import Settings allows you to restore a previous configuration. Reset Settings will restore all settings to their defaults. Reset Usage will clear all usage statistics and start fresh."), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
gap: '10px',
marginBottom: '10px'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_34__.NekoButton, {
className: "blue",
onClick: onExportSettings,
style: {
flex: 2
}
}, "Export Settings"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_34__.NekoButton, {
className: "danger",
onClick: onImportSettings,
style: {
flex: 1
}
}, "Import Settings"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_34__.NekoButton, {
className: "danger",
onClick: onResetSettings,
style: {
flex: 1
}
}, "Reset Settings")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_34__.NekoButton, {
className: "danger",
onClick: async () => {
if (window.confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.RESET_USAGE_SURE)) {
setBusyAction(true);
try {
// Reset the usage data using the regular update endpoint
await updateOption([], 'ai_usage');
await updateOption([], 'ai_usage_daily');
// Fetch fresh options from the server to ensure cache is refreshed
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/settings/options`, {
method: 'GET',
headers: {
'X-WP-Nonce': _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce
}
});
if (response.success && response.options) {
// Update with the fresh data from server
updateOptions(response.options);
showSnackbar('Usage data has been reset successfully.', 'success');
}
} catch (error) {
console.error('Error resetting usage:', error);
showSnackbar('Failed to reset usage data. Please try again.', 'error');
} finally {
setBusyAction(false);
}
}
},
disabled: busy,
fullWidth: true
}, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.RESET, " ", _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.USAGE)), settingsSection === 'remote' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: "Model Context Protocol (MCP)",
className: "primary"
}, /*#__PURE__*/React.createElement("p", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.MCP_INTRO)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, null), jsxMcpModule, jsxMcpBearerToken, jsxMcpNoAuthUrl, (options === null || options === void 0 ? void 0 : options.module_mcp) && /*#__PURE__*/React.createElement(React.Fragment, null, jsxMcpCore, jsxMcpPlugins, jsxMcpThemes, jsxMcpDynamicRest)), (options === null || options === void 0 ? void 0 : options.module_mcp) && /*#__PURE__*/React.createElement(_app_components_MCPFunctions__WEBPACK_IMPORTED_MODULE_35__["default"], {
options: options
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoColumn, {
minimal: true
}, settingsSection === 'ai' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.GENERAL,
className: "primary"
}, jsxStream, jsxEventLogs, jsxResponsesApi)), settingsSection === 'knowledge' && module_embeddings && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
className: "primary",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DEFAULTS
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("strong", null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.AI_ENVIRONMENT, ":"), " ", options !== null && options !== void 0 && options.ai_embeddings_default_env ? options === null || options === void 0 || (_options$ai_envs = options.ai_envs) === null || _options$ai_envs === void 0 || (_options$ai_envs = _options$ai_envs.find(env => env.id === options.ai_embeddings_default_env)) === null || _options$ai_envs === void 0 ? void 0 : _options$ai_envs.name : (options === null || options === void 0 || (_options$ai_envs2 = options.ai_envs) === null || _options$ai_envs2 === void 0 || (_options$ai_envs2 = _options$ai_envs2[0]) === null || _options$ai_envs2 === void 0 ? void 0 : _options$ai_envs2.name) || 'OpenAI', /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.EMBEDDINGS_MODEL, ":"), " ", (options === null || options === void 0 ? void 0 : options.ai_embeddings_default_model) || 'text-embedding-3-small', /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DIMENSIONS, ":"), " ", (options === null || options === void 0 ? void 0 : options.ai_embeddings_default_dimensions) || 1536), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 10,
fontSize: '0.9em',
fontStyle: 'italic'
}
}, "If a particular embeddings environment needs different settings, use the \"Override Defaults\" option in the AI Environment section of each embeddings environment.")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
className: "primary",
title: "Embeddings Search",
style: {
marginTop: 10
},
busy: busyEmbeddingsSearch
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Method"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
value: (options === null || options === void 0 || (_options$embeddings_s = options.embeddings_settings) === null || _options$embeddings_s === void 0 ? void 0 : _options$embeddings_s.search_method) || 'simple',
onChange: value => updateEmbeddingsSearchOption({
...options.embeddings_settings,
search_method: value
}),
description: "Choose how to build search queries from conversations."
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "simple",
label: "Simple"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "context_aware",
label: "Context-Aware"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "smart_search",
label: "Smart Search"
}))), ((options === null || options === void 0 || (_options$embeddings_s2 = options.embeddings_settings) === null || _options$embeddings_s2 === void 0 ? void 0 : _options$embeddings_s2.search_method) === 'context_aware' || (options === null || options === void 0 || (_options$embeddings_s3 = options.embeddings_settings) === null || _options$embeddings_s3 === void 0 ? void 0 : _options$embeddings_s3.search_method) === 'smart_search' || (options === null || options === void 0 || (_options$embeddings_s4 = options.embeddings_settings) === null || _options$embeddings_s4 === void 0 ? void 0 : _options$embeddings_s4.search_method) === 'user_messages' || (options === null || options === void 0 || (_options$embeddings_s5 = options.embeddings_settings) === null || _options$embeddings_s5 === void 0 ? void 0 : _options$embeddings_s5.search_method) === 'ai_optimized') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Messages"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoInput, {
type: "number",
value: (options === null || options === void 0 || (_options$embeddings_s6 = options.embeddings_settings) === null || _options$embeddings_s6 === void 0 ? void 0 : _options$embeddings_s6.context_messages) || 10,
min: 1,
max: 20,
onFinalChange: value => updateEmbeddingsSearchOption({
...options.embeddings_settings,
context_messages: parseInt(value) || 10
}),
description: "Number of recent messages to consider for context."
})), ((options === null || options === void 0 || (_options$embeddings_s7 = options.embeddings_settings) === null || _options$embeddings_s7 === void 0 ? void 0 : _options$embeddings_s7.search_method) === 'smart_search' || (options === null || options === void 0 || (_options$embeddings_s8 = options.embeddings_settings) === null || _options$embeddings_s8 === void 0 ? void 0 : _options$embeddings_s8.search_method) === 'ai_optimized') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSettings, {
title: "Instructions"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoCheckbox, {
name: "include_instructions",
label: "Enable",
value: "1",
checked: (options === null || options === void 0 || (_options$embeddings_s9 = options.embeddings_settings) === null || _options$embeddings_s9 === void 0 ? void 0 : _options$embeddings_s9.include_instructions) || false,
onChange: () => {
var _options$embeddings_s10;
return updateEmbeddingsSearchOption({
...options.embeddings_settings,
include_instructions: !(options !== null && options !== void 0 && (_options$embeddings_s10 = options.embeddings_settings) !== null && _options$embeddings_s10 !== void 0 && _options$embeddings_s10.include_instructions || false)
});
},
description: "Include chatbot instructions in search queries."
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
className: "primary",
title: "Information",
style: {
marginTop: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 20
}
}, /*#__PURE__*/React.createElement("p", null, "Embeddings are textual data converted into vectors that enable similarity search. They allow AI to find relevant context from your knowledge base, synchronized with vector databases like Pinecone or Qdrant for efficient storage and retrieval. When enabled in chatbots or forms, AI Engine searches your knowledge base for relevant context to enrich responses. Both chatbots and AI Forms can use embeddings to provide more contextual answers."), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 15
}
}, /*#__PURE__*/React.createElement("strong", null, "Working with Embeddings")), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 5
}
}, "Access the ", /*#__PURE__*/React.createElement("b", null, "Knowledge"), " tab to manage your embeddings, where you can:"), /*#__PURE__*/React.createElement("ul", {
style: {
marginTop: 5,
marginLeft: 20
}
}, /*#__PURE__*/React.createElement("li", null, "Create, edit, and search embeddings (", /*#__PURE__*/React.createElement("strong", null, "EDIT"), ")."), /*#__PURE__*/React.createElement("li", null, "Query your knowledge base directly (", /*#__PURE__*/React.createElement("strong", null, "AI SEARCH"), ")."), /*#__PURE__*/React.createElement("li", null, "Use Sync to process posts and create/update embeddings.")), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 15
}
}, /*#__PURE__*/React.createElement("strong", null, "Embeddings Search")), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 5
}
}, "Configure how AI Engine searches your knowledge base when processing conversations. The search method determines what context is used to find relevant embeddings:"), /*#__PURE__*/React.createElement("ul", {
style: {
marginTop: 5,
marginLeft: 20
}
}, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Last Message Only:"), " Uses only the last message for context (default, fastest)."), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Recent User Messages:"), " Includes more conversation history for better context."), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "AI-Optimized Query:"), " Uses AI to create smarter searches based on full context (uses Default Fast model, additional costs apply).")), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 15
}
}, "Learn more in the ", /*#__PURE__*/React.createElement("a", {
href: "https://ai.thehiddendocs.com/embeddings/",
target: "_blank"
}, "documentation"), " or join the ", /*#__PURE__*/React.createElement("a", {
href: "https://discord.gg/bHDGh38",
target: "_blank"
}, "Discord Server"), " to discuss embeddings with other users.")))), settingsSection === 'chatbot' && /*#__PURE__*/React.createElement(React.Fragment, null, chatbot_discussions && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DISCUSSIONS,
className: "primary"
}, jsxDiscussionSummary, jsxDiscussionsPaging, jsxDiscussionsRefreshInterval, jsxDiscussionsMetadata, jsxDiscussionsMetadataOptions), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.USER_INTERFACE,
className: "primary"
}, jsxChatbotSelection)), settingsSection === 'orchestration' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
className: "primary",
title: "Information"
}, /*#__PURE__*/React.createElement("p", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].SETTINGS.ORCHESTRATION_INFO))), settingsSection === 'remote' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.REST_API,
className: "primary"
}, /*#__PURE__*/React.createElement("p", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].HELP.REST_API_INTRO)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoSpacer, null), jsxPublicAPI, jsxBearerToken), settingsSection === 'remote' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
className: "primary",
title: "Information"
}, /*#__PURE__*/React.createElement("p", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].SETTINGS.REMOTE_ACCESS_INFO))), settingsSection === 'files' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: "Generated by AI",
className: "primary"
}, jsxImageLocalDownload, (options === null || options === void 0 ? void 0 : options.image_local_download) !== null && jsxImageExpirationDownload), settingsSection === 'others' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ADVANCED,
className: "primary"
}, jsxResolveShortcodes, jsxContextMaxTokens, jsxDevTools, jsxCleanUninstall), settingsSection === 'others' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: "Languages",
className: "primary"
}, jsxCustomLanguages), settingsSection === 'others' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoBlock, {
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SECURITY,
className: "primary"
}, jsxPrivacyFirst, jsxBannedKeywords, (banned_words === null || banned_words === void 0 ? void 0 : banned_words.length) > 0 && jsxIgnoreWordBoundaries, jsxBannedIPs)))))), module_devtools && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "devtools",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.DEV_TOOLS
}, /*#__PURE__*/React.createElement(_settings_DevToolsTab__WEBPACK_IMPORTED_MODULE_36__["default"], {
options: options,
setOptions: setOptions,
updateOption: updateOption,
busy: busy
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTab, {
key: "license",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.LICENSE_TAB
}, /*#__PURE__*/React.createElement(_common__WEBPACK_IMPORTED_MODULE_37__.LicenseBlock, {
domain: _app_settings__WEBPACK_IMPORTED_MODULE_0__.domain,
prefix: _app_settings__WEBPACK_IMPORTED_MODULE_0__.prefix,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isPro,
isRegistered: _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered
}))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_38__.NekoModal, {
isOpen: error,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ERROR,
content: error,
onRequestClose: () => setError(false),
okButton: {
label: "Close",
onClick: () => setError(false)
}
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Settings);
/***/ }),
/***/ "./app/js/screens/ai/Environments.js":
/*!*******************************************!*\
!*** ./app/js/screens/ai/Environments.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useCallback,
useMemo,
useState
} = wp.element;
const Deployments = ({
updateEnvironment,
environmentId,
deployments,
options
}) => {
const updateDeployments = (index, field, value) => {
const freshDeployments = JSON.parse((0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(deployments));
freshDeployments[index][field] = value;
updateEnvironment(environmentId, {
deployments: freshDeployments
});
};
const addDeployment = () => {
const freshDeployments = [...deployments, {
name: '',
model: ''
}];
updateEnvironment(environmentId, {
deployments: freshDeployments
});
};
const removeDeployment = index => {
const freshDeployments = [...deployments];
freshDeployments.splice(index, 1);
updateEnvironment(environmentId, {
deployments: freshDeployments
});
};
const OpenAIModels = useMemo(() => {
var _options$ai_engines;
const openAI = options === null || options === void 0 || (_options$ai_engines = options.ai_engines) === null || _options$ai_engines === void 0 ? void 0 : _options$ai_engines.find(x => x.type === 'openai');
return (openAI === null || openAI === void 0 ? void 0 : openAI.models) ?? [];
}, [options]);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.OPENAI_AZURE_DEPLOYMENTS,
style: {
marginTop: 10
}
}, deployments.map((deployment, index) => /*#__PURE__*/React.createElement("div", {
key: index,
style: {
display: 'flex',
marginBottom: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
style: {
flex: 1
},
value: deployment['name'],
placeholder: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.OPENAI_AZURE_DEPLOYMENT_NAME,
onBlur: value => updateDeployments(index, 'name', value),
onEnter: value => updateDeployments(index, 'name', value)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSelect, {
style: {
flex: 1,
marginLeft: 10
},
scrolldown: true,
id: "model",
name: "model",
value: deployment['model'],
onChange: value => updateDeployments(index, 'model', value)
}, OpenAIModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
rounded: true,
isSmall: true,
style: {
marginLeft: 10,
height: 30
},
icon: "trash",
onClick: () => removeDeployment(index)
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
fullWidth: true,
icon: "plus",
onClick: addDeployment
}));
};
const CustomModels = ({
updateEnvironment,
environmentId,
customModels
}) => {
const updateCustomModels = (index, field, value) => {
const freshCustomModels = JSON.parse((0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(customModels));
freshCustomModels[index][field] = value;
updateEnvironment(environmentId, {
customModels: freshCustomModels
});
};
// The tags 'core' and 'chat' will always be added and kept in the custom models.
const addCustomModel = () => {
const freshCustomModels = [...customModels, {
name: '',
apiUrl: '',
tags: ['core', 'chat']
}];
updateEnvironment(environmentId, {
customModels: freshCustomModels
});
};
const removeCustomModel = index => {
const freshCustomModels = [...customModels];
freshCustomModels.splice(index, 1);
updateEnvironment(environmentId, {
customModels: freshCustomModels
});
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HUGGINGFACE_MODELS,
style: {
marginTop: 10
}
}, customModels.map((customModel, index) => {
var _customModel$tags, _customModel$tags2;
return /*#__PURE__*/React.createElement("div", {
key: index,
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("div", {
key: index,
style: {
display: 'flex',
marginBottom: 2
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
style: {
flex: 1
},
value: customModel['name'],
placeholder: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HUGGINGFACE_MODEL_NAME,
onBlur: value => updateCustomModels(index, 'name', value),
onEnter: value => updateCustomModels(index, 'name', value)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
style: {
flex: 2,
marginLeft: 5
},
value: customModel['apiUrl'],
placeholder: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HUGGINGFACE_MODEL_URL,
onBlur: value => updateCustomModels(index, 'apiUrl', value),
onEnter: value => updateCustomModels(index, 'apiUrl', value)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
rounded: true,
isSmall: true,
style: {
marginLeft: 5,
height: 30
},
icon: "trash",
onClick: () => removeCustomModel(index)
})), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement("span", {
style: {
marginRight: 5
}
}, "Image Model"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckbox, {
style: {
marginTop: !index ? 5 : 0,
marginRight: 10
},
disabled: true,
checked: (_customModel$tags = customModel['tags']) === null || _customModel$tags === void 0 ? void 0 : _customModel$tags.includes('image'),
onChange: value => {
const freshCustomModels = JSON.parse((0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(customModels));
if (!freshCustomModels[index]['tags']) {
freshCustomModels[index]['tags'] = ['core', 'chat'];
}
if (value) {
freshCustomModels[index]['tags'].push('image');
} else {
freshCustomModels[index]['tags'] = freshCustomModels[index]['tags'].filter(x => x !== 'image');
}
updateEnvironment(environmentId, {
customModels: freshCustomModels
});
}
}), /*#__PURE__*/React.createElement("span", {
style: {
marginRight: 5
}
}, "Vision Model"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoCheckbox, {
style: {
marginTop: !index ? 5 : 0,
marginRight: 33
},
disabled: true,
checked: (_customModel$tags2 = customModel['tags']) === null || _customModel$tags2 === void 0 ? void 0 : _customModel$tags2.includes('vision'),
onChange: value => {
const freshCustomModels = JSON.parse((0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(customModels));
if (!freshCustomModels[index]['tags']) {
freshCustomModels[index]['tags'] = ['core', 'chat'];
}
if (value) {
freshCustomModels[index]['tags'].push('vision');
} else {
freshCustomModels[index]['tags'] = freshCustomModels[index]['tags'].filter(x => x !== 'vision');
}
updateEnvironment(environmentId, {
customModels: freshCustomModels
});
}
})));
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
fullWidth: true,
icon: "plus",
onClick: addCustomModel
}));
};
function AIEnvironmentsSettings({
options,
environments,
updateEnvironment,
updateOption,
busy
}) {
const [loading, setLoading] = useState(false);
const [testBusy, setTestBusy] = useState(false);
const [testResults, setTestResults] = useState(null);
const aiEngines = (options === null || options === void 0 ? void 0 : options.ai_engines) ?? [];
const addNewEnvironment = () => {
const newEnv = {
//id: Date.now(), // Assuming id is a timestamp for uniqueness
name: 'New Environment',
type: 'openai',
apikey: ''
};
const updatedEnvironments = [...environments, newEnv];
updateOption(updatedEnvironments, 'ai_envs');
};
const deleteEnvironment = id => {
if (environments.length === 1) {
alert("You can't delete the last environment.");
return;
}
const updatedEnvironments = environments.filter(env => env.id !== id);
updateOption(updatedEnvironments, 'ai_envs');
};
const getDescription = useCallback(env => {
switch (env.type) {
case 'openai':
return (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.OPENAI_API_KEY);
case 'azure':
return (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.AZURE_API_KEY);
case 'openrouter':
return (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.OPENROUTER_API_KEY);
case 'anthropic':
return (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.ANTHROPIC_API_KEY);
default:
return '';
}
}, []);
const fetchModels = useCallback(async (envId, envType) => {
try {
setLoading(true);
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_7__.apiUrl}/ai/models`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_7__.restNonce,
json: {
envId
}
});
setLoading(false);
let newModels = res === null || res === void 0 ? void 0 : res.models;
if (!newModels) {
throw new Error('Could not fetch models.');
}
// After fetching, we need to update the options with the new models.
// We need to filter out the old models and add the new ones.
newModels = newModels.map(x => ({
...x,
envId,
type: envType
}));
let freshModels = (options === null || options === void 0 ? void 0 : options.ai_models) ?? [];
freshModels = freshModels.filter(x => !(x.type === envType && (!x.envId || x.envId === envId)));
freshModels.push(...newModels);
updateOption(freshModels, 'ai_models');
} catch (err) {
alert(err.message);
// eslint-disable-next-line no-console
console.log(err);
setLoading(false);
}
}, [updateOption]);
const handleQuickTest = useCallback(async env => {
setTestBusy(true);
try {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_7__.apiUrl}/ai/test_connection`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_7__.restNonce,
json: {
env_id: env.id
}
});
setTestResults(response);
} catch (error) {
setTestResults({
success: false,
error: error.message || 'Failed to test connection',
provider: env.type
});
} finally {
setTestBusy(false);
}
}, []);
const renderFields = env => {
const currentEngine = aiEngines.find(engine => engine.type === env.type) || {};
const fields = currentEngine.inputs || [];
return /*#__PURE__*/React.createElement(React.Fragment, null, fields.includes('apikey') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.API_KEY
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "apikey",
value: env.apikey,
description: getDescription(env),
onFinalChange: value => updateEnvironment(env.id, {
apikey: value
})
})), fields.includes('organizationId') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.OPENAI_ORGANIZATION_ID
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "organizationId",
value: env.organizationId,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.OPENAI_ORGANIZATION_ID),
onFinalChange: value => updateEnvironment(env.id, {
organizationId: value
})
})), fields.includes('endpoint') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENDPOINT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "endpoint",
value: env.endpoint,
onFinalChange: value => updateEnvironment(env.id, {
endpoint: value
})
})), fields.includes('region') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.REGION
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "region",
value: env.region,
onFinalChange: value => updateEnvironment(env.id, {
region: value
})
})), fields.includes('projectId') && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.PROJECT_ID
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "projectId",
value: env.projectId,
onFinalChange: value => updateEnvironment(env.id, {
projectId: value
})
})));
};
return /*#__PURE__*/React.createElement("div", {
style: {
padding: '0px 10px 5px 10px',
marginTop: 13,
marginBottom: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 15
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENVIRONMENTS_FOR_AI), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoTabs, {
inversed: true,
style: {
marginTop: -5
},
action: /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
rounded: true,
className: "secondary",
icon: "plus",
onClick: addNewEnvironment
})
}, environments.map(env => {
var _currentEngine$inputs;
let modelsCount = 0;
const currentEngine = aiEngines.find(engine => engine.type === env.type) || {};
const hasDynamicModels = (_currentEngine$inputs = currentEngine.inputs) === null || _currentEngine$inputs === void 0 ? void 0 : _currentEngine$inputs.includes('dynamicModels');
if (Array.isArray(currentEngine.models)) {
modelsCount = currentEngine.models.length;
}
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoTab, {
key: env.id,
title: env.name,
busy: busy
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.NAME
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "name",
value: env.name,
onFinalChange: value => updateEnvironment(env.id, {
name: value
})
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.TYPE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSelect, {
scrolldown: true,
name: "type",
value: env.type,
onChange: value => updateEnvironment(env.id, {
type: value
})
}, aiEngines.map(engine => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoOption, {
key: engine.type,
value: engine.type,
label: engine.name
})))), renderFields(env), env.type === 'google' && /*#__PURE__*/React.createElement(React.Fragment, null, (env.apikey === '' || !env.apikey) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "info",
style: {
marginBottom: 10
}
}, "Click ", /*#__PURE__*/React.createElement("a", {
href: "https://aistudio.google.com/app/apikey",
target: "_blank",
rel: "noreferrer"
}, "here"), " to access AI Studio and create your API Key."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "danger"
}, "Streaming is only supported in the Pro Version of AI Engine. As of 2025, Gemini is still unstable. If you encounter issues, let's discuss them on ", /*#__PURE__*/React.createElement("a", {
href: "https://discord.gg/bHDGh38",
target: "_blank",
rel: "noreferrer"
}, "Discord"), "."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoSpacer, null)), env.type === 'huggingface' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "danger"
}, "Support for Hugging Face is experimental and may not work as expected. Also, AI Engine is ready for Image and Vision but Hugging Face is not (hence the disabled checkboxes). Let's discuss about Hugging Face on ", /*#__PURE__*/React.createElement("a", {
href: "https://discord.gg/bHDGh38",
target: "_blank",
rel: "noreferrer"
}, "Discord"), "."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoSpacer, null)), env.type === 'perplexity' && (env.apikey === '' || !env.apikey) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "warning"
}, "Perplexity.ai is a paid service. Click ", /*#__PURE__*/React.createElement("a", {
href: "https://perplexity.ai/pro?referral_code=A1R94DGZ",
target: "_blank",
rel: "noreferrer"
}, "here"), " to create an account with 10$ free credit."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoSpacer, null)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoAccordions, {
keepState: "environmentCategories"
}, hasDynamicModels && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MODELS
}, env.type === 'openrouter' && /*#__PURE__*/React.createElement("p", null, "There are currently ", /*#__PURE__*/React.createElement("b", null, modelsCount), " models available. OpenRouter models need to be refresh regularly. This button will fetch the latest models and their prices."), env.type === 'google' && /*#__PURE__*/React.createElement("p", null, "There are currently ", /*#__PURE__*/React.createElement("b", null, modelsCount), " models available. Google models need to be refresh regularly. This button will fetch the latest models and their prices."), env.type !== 'openrouter' && env.type !== 'google' && /*#__PURE__*/React.createElement("p", null, "There are currently ", /*#__PURE__*/React.createElement("b", null, modelsCount), " models available. This button will fetch the latest models."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
fullWidth: true,
className: "primary",
isBusy: loading,
onClick: () => fetchModels(env.id, env.type)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.REFRESH_MODELS)), env.type === 'azure' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.AZURE_DEPLOYMENTS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.OPENAI_AZURE_DEPLOYMENTS
}, /*#__PURE__*/React.createElement(Deployments, {
deployments: env.deployments ?? [],
environmentId: env.id,
updateEnvironment: updateEnvironment,
options: options
}))), env.type === 'huggingface' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HUGGINGFACE_MODELS
}, /*#__PURE__*/React.createElement("p", null, "Browse the ", /*#__PURE__*/React.createElement("a", {
href: "https://huggingface.co/models",
target: "_blank",
rel: "noreferrer"
}, "Models on Hugging Face"), ". Use the Deploy button (Inference API Serverless) in order to get the API URL. Paste it below with the name of your choice and you're done!"), /*#__PURE__*/React.createElement(CustomModels, {
customModels: env.customModels ?? [],
environmentId: env.id,
updateEnvironment: updateEnvironment,
options: options
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENVIRONMENT_ID
}, /*#__PURE__*/React.createElement("p", null, "The EnvID is \"", /*#__PURE__*/React.createElement("b", null, env.id), "\".")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ACTIONS
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "primary",
isBusy: testBusy,
onClick: () => handleQuickTest(env)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.QUICK_TEST || 'Quick Test'), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "danger",
onClick: () => deleteEnvironment(env.id)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.DELETE)))));
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoModal, {
isOpen: !!testResults,
onRequestClose: () => setTestResults(null),
title: "Connection Test Results",
okButton: {
label: 'Close',
onClick: () => setTestResults(null)
},
content: testResults && /*#__PURE__*/React.createElement("div", null, testResults.success ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "success"
}, "Connection successful!"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoSpacer, null), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Provider:"), " ", testResults.provider, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Environment:"), " ", testResults.name, /*#__PURE__*/React.createElement("br", null), testResults.data && /*#__PURE__*/React.createElement(React.Fragment, null, testResults.provider === 'openai' && testResults.data.models && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Available Models:"), " ", testResults.data.models.length, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Sample Models:"), " ", testResults.data.models.slice(0, 3).join(', '), testResults.data.models.length > 3 && '...'), testResults.provider === 'anthropic' && testResults.data.models && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Available Models:"), " ", testResults.data.models.length, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Models:"), " ", testResults.data.models.join(', ')), testResults.provider === 'google' && testResults.data.models && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Available Models:"), " ", testResults.data.models.length, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Sample Models:"), " ", testResults.data.models.slice(0, 3).join(', '), testResults.data.models.length > 3 && '...'), testResults.provider === 'openrouter' && testResults.data.models && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Available Models:"), " ", testResults.data.models.length, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Sample Models:"), " ", testResults.data.models.slice(0, 3).join(', '), testResults.data.models.length > 3 && '...'), testResults.provider === 'azure' && testResults.data.deployments && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Deployments:"), " ", testResults.data.deployments.length, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("strong", null, "Available:"), " ", testResults.data.deployments.join(', '))))) : /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "danger"
}, /*#__PURE__*/React.createElement("strong", null, "Connection failed!"), /*#__PURE__*/React.createElement("br", null), testResults.error))
}));
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AIEnvironmentsSettings);
/***/ }),
/***/ "./app/js/screens/assistants/Assistants.js":
/*!*************************************************!*\
!*** ./app/js/screens/assistants/Assistants.js ***!
\*************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Paging.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/table/Table.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
// React & Vendor Libs
const {
useState,
useMemo,
useEffect
} = wp.element;
// NekoUI Components
const assistantColumns = [{
accessor: 'name',
title: 'Name',
width: '30%',
verticalAlign: 'top'
}, {
accessor: 'instructions',
title: 'Instructions',
width: '40%',
verticalAlign: 'top'
}, {
accessor: 'parameters',
title: 'Parameters',
width: '20%',
verticalAlign: 'top'
}, {
accessor: 'createdOn',
title: 'Created On',
width: '10%',
verticalAlign: 'top'
}];
const fileColumns = [{
accessor: 'file',
title: 'File',
width: '30%',
verticalAlign: 'top'
}, {
accessor: 'metadata',
title: 'Metadata',
width: '30%',
verticalAlign: 'top'
}, {
accessor: 'userId',
title: 'User ID',
width: '80px',
verticalAlign: 'top'
}, {
accessor: 'purpose',
title: 'Purpose',
width: '20%',
verticalAlign: 'top'
}, {
accessor: 'created',
title: 'Created On',
width: '20%',
verticalAlign: 'top'
}, {
accessor: 'actions',
title: 'Actions',
width: '60px',
verticalAlign: 'top'
}];
const getLocalSettings = () => {
const localSettingsJSON = localStorage.getItem('mwai-admin-assistants');
try {
return JSON.parse(localSettingsJSON);
} catch (e) {
return {};
}
};
const setLocalSettings = ({
envId
}) => {
const settings = {
envId: envId || null
};
localStorage.setItem('mwai-admin-assistants', (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(settings));
};
const Assistants = ({
options,
refreshOptions
}) => {
var _options$ai_envs;
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_1__.useQueryClient)();
const [errorModal, setErrorModal] = useState(null);
const [busyAction, setBusyAction] = useState(false);
const [envId, setEnvId] = useState(options === null || options === void 0 || (_options$ai_envs = options.ai_envs) === null || _options$ai_envs === void 0 || (_options$ai_envs = _options$ai_envs[0]) === null || _options$ai_envs === void 0 ? void 0 : _options$ai_envs.id);
const [section, setSection] = useState('assistants');
const [selectedIds, setSelectedIds] = useState([]);
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.useNekoColors)();
const environments = useMemo(() => {
var _options$ai_envs2;
return (options === null || options === void 0 || (_options$ai_envs2 = options.ai_envs) === null || _options$ai_envs2 === void 0 ? void 0 : _options$ai_envs2.filter(x => x.type === 'openai' || x.type === 'azure')) || [];
}, [options]);
const environment = useMemo(() => environments.find(x => x.id === envId), [envId, environments]);
const allAssistants = useMemo(() => (environment === null || environment === void 0 ? void 0 : environment.assistants) || [], [environment]);
const [filesQueryParams, setFilesQueryParams] = useState({
userId: null,
purpose: ['assistant-in', 'assistant-out'],
metadata: null,
envId: envId,
page: 1,
limit: 10
});
const queryParamsChecksum = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(filesQueryParams);
// Initialize the environment from localSettings with useEffect
useEffect(() => {
const localSettings = getLocalSettings();
const defaultEnvId = (localSettings === null || localSettings === void 0 ? void 0 : localSettings.envId) ?? null;
if (defaultEnvId) {
setEnvId(defaultEnvId);
}
}, []);
useEffect(() => {
setLocalSettings({
envId
});
}, [envId]);
useEffect(() => {
setFilesQueryParams({
...filesQueryParams,
envId
});
}, [envId]);
const {
isFetching: isBusyFiles,
data: dataFiles
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_3__.useQuery)({
queryKey: ['assistants-files', queryParamsChecksum],
enabled: section === 'files',
staleTime: 1000 * 60 * 5,
queryFn: () => (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.retrieveFiles)(filesQueryParams)
});
const resolveAssistantName = assistantId => {
const assistant = allAssistants.find(x => x.id === assistantId);
return (assistant === null || assistant === void 0 ? void 0 : assistant.name) || 'N/A';
};
const renderMetadata = metadata => {
if (!metadata) {
return null;
}
return /*#__PURE__*/React.createElement("small", null, /*#__PURE__*/React.createElement("ul", {
style: {
margin: 0,
padding: 0
}
}, Object.keys(metadata).map(key => /*#__PURE__*/React.createElement("li", {
key: key,
style: {
margin: 0
}
}, /*#__PURE__*/React.createElement("i", null, key), ": ", metadata[key], " ", key === 'assistant_id' ? `(${resolveAssistantName(metadata[key])})` : ''))));
};
const renderLink = url => {
if (!url) {
return null;
}
const filename = url.split('/').pop();
return /*#__PURE__*/React.createElement("a", {
href: url,
target: "_blank",
rel: "noreferrer"
}, filename);
};
const renderPurpose = purpose => {
if (purpose === 'assistant-out') {
return 'Generated';
}
if (purpose === 'assistant-in') {
return 'Uploaded';
}
return purpose;
};
const renderFile = (url, refId) => {
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("span", null, renderLink(url)), /*#__PURE__*/React.createElement("small", null, refId));
};
const onDeleteFile = async fileIds => {
setBusyAction(true);
try {
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.deleteFiles)(fileIds);
await queryClient.invalidateQueries('assistants-files');
setSelectedIds([]);
} catch (err) {
setErrorModal(err);
}
setBusyAction(false);
};
const fileRows = useMemo(() => {
return dataFiles === null || dataFiles === void 0 ? void 0 : dataFiles.files.map(file => ({
...file,
file: renderFile(file.url, file.refId),
purpose: renderPurpose(file.purpose),
metadata: renderMetadata(file.metadata),
created: new Date(file.created).toLocaleDateString(),
actions: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "danger",
rounded: true,
icon: "trash",
disabled: busyAction,
onClick: () => onDeleteFile([file.id])
}))
}));
}, [dataFiles]);
const fileTotal = useMemo(() => {
return (dataFiles === null || dataFiles === void 0 ? void 0 : dataFiles.total) || 0;
}, [dataFiles]);
const onRefreshAssistants = async () => {
setBusyAction(true);
try {
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_4__.retrieveAssistants)(envId);
await refreshOptions();
} catch (err) {
setErrorModal(err);
}
setBusyAction(false);
};
const onRefreshFiles = async () => {
await queryClient.invalidateQueries('assistants-files');
};
const assistantRows = useMemo(() => {
return allAssistants.map(assistant => {
var _assistant$instructio;
return {
...assistant,
name: /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("span", null, assistant.name), /*#__PURE__*/React.createElement("small", null, assistant.id)),
instructions: ((_assistant$instructio = assistant.instructions) === null || _assistant$instructio === void 0 ? void 0 : _assistant$instructio.length) > 100 ? `${assistant.instructions.slice(0, 100)}...` : assistant.instructions,
parameters: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("ul", {
style: {
margin: 0,
padding: 0
}
}, /*#__PURE__*/React.createElement("li", {
style: {
margin: 0,
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoIcon, {
icon: "check",
width: 16,
color: colors.green
}), /*#__PURE__*/React.createElement("span", {
style: {
marginLeft: 3
}
}, assistant.model ?? 'Unknown')), !assistant.model && /*#__PURE__*/React.createElement("li", {
style: {
margin: 0,
display: 'flex',
lineHeight: '12px'
}
}, /*#__PURE__*/React.createElement("small", null, "The model could not be found in your AI environment. Please make sure it exists as a deployment, and Refresh the list of Assistants.")), /*#__PURE__*/React.createElement("li", {
style: {
margin: 0,
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoIcon, {
icon: assistant.has_file_search ? 'check' : 'close',
width: 16,
color: assistant.has_file_search ? colors.green : colors.gray
}), /*#__PURE__*/React.createElement("a", {
style: {
marginLeft: 3
},
href: "https://platform.openai.com/docs/assistants/tools/file-search",
target: "_blank",
rel: "noreferrer"
}, "File Search")), /*#__PURE__*/React.createElement("li", {
style: {
margin: 0,
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoIcon, {
icon: assistant.has_code_interpreter ? 'check' : 'close',
width: 16,
color: assistant.has_code_interpreter ? colors.green : colors.gray
}), /*#__PURE__*/React.createElement("a", {
style: {
marginLeft: 3
},
href: "https://platform.openai.com/docs/assistants/tools/code-interpreter",
target: "_blank",
rel: "noreferrer"
}, "Code Interpreter")))),
createdOn: new Date(assistant.createdOn).toLocaleDateString()
};
});
}, [allAssistants, colors.gray, colors.green]);
const busy = busyAction;
const jsxEnvironments = useMemo(() => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSelect, {
scrolldown: true,
value: envId,
onChange: setEnvId,
style: {
marginLeft: 5
}
}, environments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
}))), [envId, environments]);
const jsxPaging = useMemo(() => {
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'row'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoPaging, {
currentPage: filesQueryParams.page,
limit: filesQueryParams.limit,
total: fileTotal,
onClick: page => {
setFilesQueryParams({
...filesQueryParams,
page
});
}
})));
}, [filesQueryParams, fileTotal]);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoColumn, {
fullWidth: true,
minimal: true,
style: {
margin: 8
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoTabs, {
inversed: true,
currentTab: section,
onChange: (_index, attributes) => {
setSection(attributes.key);
},
action: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), selectedIds.length > 0 && section === 'files' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "danger",
disabled: false,
onClick: () => onDeleteFile(selectedIds)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.DELETE)), section === 'files' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
disabled: busy || !environment,
busy: busy,
onClick: onRefreshFiles,
className: "secondary"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.REFRESH), section === 'assistants' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
disabled: busy || !environment,
busy: busy,
onClick: onRefreshAssistants,
className: "secondary"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.REFRESH), jsxEnvironments)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.ASSISTANTS,
key: "assistants"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoTable, {
busy: busy,
data: assistantRows,
columns: assistantColumns,
emptyMessage: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].NO_ASSISTANTS_YET
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.FILES,
key: "files"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoTable, {
busy: isBusyFiles || busy,
data: fileRows,
columns: fileColumns,
selectedItems: selectedIds,
onSelect: ids => {
setSelectedIds([...selectedIds, ...ids]);
},
onUnselect: ids => {
setSelectedIds([...selectedIds.filter(x => !ids.includes(x))]);
},
emptyMessage: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].NO_FILES_YET
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
marginTop: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), jsxPaging)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoColumn, {
fullWidth: true,
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoBlock, {
className: "primary"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoTypo, {
p: true
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].HELP.ASSISTANTS_INTRO)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoMessage, {
variant: "danger"
}, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].HELP.ASSISTANTS_WARNINGS))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
tiny: true
}), errorModal && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoModal, {
isOpen: !!errorModal,
title: "Error",
onRequestClose: () => setErrorModal(null),
okButton: {
label: 'Ok',
onClick: () => setErrorModal(null)
},
content: /*#__PURE__*/React.createElement("p", null, errorModal === null || errorModal === void 0 ? void 0 : errorModal.message)
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Assistants);
/***/ }),
/***/ "./app/js/screens/chatbots/Chatbots.js":
/*!*********************************************!*\
!*** ./app/js/screens/chatbots/Chatbots.js ***!
\*********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/toolbar/Toolbar.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Switch.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* harmony import */ var _app_screens_chatbots_Params__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @app/screens/chatbots/Params */ "./app/js/screens/chatbots/Params.js");
/* harmony import */ var _app_screens_chatbots_Themes__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @app/screens/chatbots/Themes */ "./app/js/screens/chatbots/Themes.js");
/* harmony import */ var _app_chatbot_ChatbotSystem__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @app/chatbot/ChatbotSystem */ "./app/js/chatbot/ChatbotSystem.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _Shortcode__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Shortcode */ "./app/js/screens/chatbots/Shortcode.js");
// React & Vendor Libs
const {
useMemo,
useState,
useEffect
} = wp.element;
// NekoUI
// Function to keep the current chatbot key in the browser storage.
const setCurrentChatbotKey = key => {
if (key) {
localStorage.setItem('mwai-admin-chatbotKey', key);
return;
}
localStorage.removeItem('mwai-admin-chatbotKey');
};
// Function to get the current chatbot key from the browser storage.
const getCurrentChatbotKey = () => {
return localStorage.getItem('mwai-admin-chatbotKey');
};
const Chatbots = props => {
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__.useQueryClient)();
const {
options,
updateOption,
busy
} = props;
const [editor, setEditor] = useState('chatbots');
const [busyAction, setBusyAction] = useState(false);
const [currentKey, setCurrentKey] = useState(() => getCurrentChatbotKey() || 'chatbot-key-0');
const chatbotDefaults = options === null || options === void 0 ? void 0 : options.chatbot_defaults;
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.useNekoColors)();
const {
data: chatbots
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_2__.useQuery)({
queryKey: ['chatbots'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_3__.retrieveChatbots,
initialData: _app_settings__WEBPACK_IMPORTED_MODULE_4__.chatbots
});
const {
data: themes
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_2__.useQuery)({
queryKey: ['themes'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_3__.retrieveThemes,
initialData: _app_settings__WEBPACK_IMPORTED_MODULE_4__.themes
});
const botId = (options === null || options === void 0 ? void 0 : options.botId) ?? 'none';
const chatbotSelect = (options === null || options === void 0 ? void 0 : options.chatbot_select) ?? 'tabs';
const isBusy = busy || busyAction;
// Create a mapping between keys and botIds
const [keyToBotId, setKeyToBotId] = useState({});
useEffect(() => {
if (chatbots) {
const newKeyToBotId = {};
chatbots.forEach((chatbot, index) => {
newKeyToBotId[`chatbot-key-${index}`] = chatbot.botId;
});
setKeyToBotId(newKeyToBotId);
// If the current key doesn't exist in the new mapping, set it to the first key
if (!currentKey || !(currentKey in newKeyToBotId)) {
const firstKey = Object.keys(newKeyToBotId)[0];
setCurrentKey(firstKey);
setCurrentChatbotKey(firstKey);
}
}
}, [chatbots, currentKey]);
const defaultChatbot = useMemo(() => {
if (chatbots) {
const chatbot = chatbots.find(chatbot => chatbot.botId === 'default');
return chatbot;
}
}, [chatbots]);
const currentChatbot = useMemo(() => {
if (chatbots && currentKey && keyToBotId[currentKey]) {
const botId = keyToBotId[currentKey];
return chatbots.find(chatbot => chatbot.botId === botId);
}
return null;
}, [chatbots, currentKey, keyToBotId]);
const currentTheme = useMemo(() => {
if (themes && currentChatbot) {
const chatTheme = themes.find(theme => theme.themeId === (currentChatbot === null || currentChatbot === void 0 ? void 0 : currentChatbot.themeId));
return chatTheme;
}
return themes.find(theme => theme.themeId === 'chatgpt');
}, [currentChatbot, themes]);
const updateChatbotParams = async (value, id) => {
if (id === 'botId' && value === 'default') {
alert("You cannot name a chatbot 'default'. Please choose another name.");
return;
}
if (id === 'botId' && value === '') {
alert("Your chatbot must have an ID.");
return;
}
if (id === 'botId' && chatbots.find(x => x.botId === value)) {
alert("This chatbot ID is already in use. Please choose another ID.");
return;
}
setBusyAction(true);
const newParams = {
...currentChatbot,
[id]: value
};
let newChatbots = [...chatbots];
if (currentChatbot) {
const botIndex = newChatbots.findIndex(x => x.botId === currentChatbot.botId);
if (botIndex !== -1) {
newChatbots[botIndex] = newParams;
newChatbots = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_3__.updateChatbots)(newChatbots);
queryClient.setQueryData(['chatbots'], newChatbots);
if (id === 'botId') {
setKeyToBotId(prev => ({
...prev,
[currentKey]: value
}));
}
}
}
setBusyAction(false);
};
const onChangeTab = (_themeIndex, attributes) => {
setCurrentKey(attributes.key);
setCurrentChatbotKey(attributes.key);
};
const onSwitchTheme = themeId => {
updateChatbotParams(themeId, 'themeId');
};
const addNewChatbot = async (defaults = chatbotDefaults) => {
setBusyAction(true);
const newName = 'New Chatbot';
const newChatId = 'chatbot-' + (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.randomHash)();
const newChatbot = {
...defaults,
botId: newChatId,
name: newName
};
delete newChatbot.functions;
const newChatbots = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_3__.updateChatbots)([...chatbots, newChatbot]);
queryClient.setQueryData(['chatbots'], newChatbots);
const newKey = `chatbot-key-${Object.keys(keyToBotId).length}`;
setKeyToBotId(prev => ({
...prev,
[newKey]: newChatId
}));
setCurrentKey(newKey);
setCurrentChatbotKey(newKey);
setBusyAction(false);
};
const deleteCurrentChatbot = async () => {
setBusyAction(true);
const currentBotId = keyToBotId[currentKey];
// Get the array of keys before deletion
const keys = Object.keys(keyToBotId);
const index = keys.indexOf(currentKey);
// Determine newCurrentKey before deletion
let newCurrentKey;
if (index > 0) {
// If there is a previous tab, select it
newCurrentKey = keys[index - 1];
} else if (keys.length > 1) {
// If no previous tab, but there are other tabs, select the next one
newCurrentKey = keys[index + 1];
} else {
// No other tabs left
newCurrentKey = null;
}
// Set the currentKey to newCurrentKey before deletion
setCurrentKey(newCurrentKey);
setCurrentChatbotKey(newCurrentKey);
// Proceed to delete the current chatbot
let newChatbots = chatbots.filter(x => x.botId !== currentBotId);
newChatbots = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_3__.updateChatbots)(newChatbots);
queryClient.setQueryData(['chatbots'], newChatbots);
// Update keyToBotId mapping
const newKeyToBotId = {
...keyToBotId
};
delete newKeyToBotId[currentKey];
setKeyToBotId(newKeyToBotId);
setBusyAction(false);
};
const resetCurrentChatbot = async () => {
setBusyAction(true);
let newChatbots = [...chatbots];
const botIndex = newChatbots.findIndex(x => x.botId === currentChatbot.botId);
newChatbots[botIndex] = {
...chatbotDefaults,
botId: currentChatbot.botId,
name: currentChatbot.name
};
newChatbots = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_3__.updateChatbots)(newChatbots);
queryClient.setQueryData(['chatbots'], newChatbots);
setBusyAction(false);
};
const duplicateCurrentChatbot = async () => {
addNewChatbot(currentChatbot);
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoColumn, {
minimal: true,
fullWidth: true,
style: {
margin: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoToolbar, null, /*#__PURE__*/React.createElement(_Shortcode__WEBPACK_IMPORTED_MODULE_8__["default"], {
currentChatbot: currentChatbot
}), /*#__PURE__*/React.createElement("label", {
style: {
marginLeft: 5
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.CHATBOTS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSwitch, {
style: {
marginLeft: 5
},
disabled: isBusy,
onLabel: '',
offLabel: '',
width: 42,
offValue: "chatbots",
onValue: "themes",
offBackgroundColor: colors.blue,
onBackgroundColor: colors.purple,
checked: editor === 'themes',
onChange: setEditor
}), /*#__PURE__*/React.createElement("label", {
style: {
marginLeft: 5
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.THEMES), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.SITE_WIDE_CHATBOT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoSelect, {
scrolldown: true,
name: "botId",
disabled: isBusy,
style: {
minWidth: 160
},
value: botId,
onChange: updateOption
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoOption, {
value: "none",
label: "None"
}), chatbots === null || chatbots === void 0 ? void 0 : chatbots.map(chat => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoOption, {
key: chat.botId,
value: chat.botId,
label: chat.name
}))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoColumn, {
minimal: true,
style: {
margin: 10,
maxWidth: '50%'
}
}, editor === 'chatbots' && /*#__PURE__*/React.createElement(React.Fragment, null, chatbotSelect === 'dropdown' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
marginBottom: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoSelect, {
scrolldown: true,
textFiltering: true,
name: "botId",
disabled: isBusy,
style: {
flex: 'auto',
marginRight: 10
},
value: currentKey,
onChange: setCurrentKey
}, chatbots === null || chatbots === void 0 ? void 0 : chatbots.map((chat, index) => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoOption, {
key: chat.botId,
value: `chatbot-key-${index}`,
label: chat.name
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
rounded: true,
className: "secondary",
icon: "plus",
disabled: isBusy,
onClick: () => addNewChatbot()
})), currentChatbot && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoContainer, {
style: {
borderRadius: 10
}
}, /*#__PURE__*/React.createElement(_app_screens_chatbots_Params__WEBPACK_IMPORTED_MODULE_14__["default"], {
style: {
margin: '-10px -10px'
},
options: options,
themes: themes,
defaultChatbot: defaultChatbot,
deleteCurrentChatbot: deleteCurrentChatbot,
resetCurrentChatbot: resetCurrentChatbot,
duplicateCurrentChatbot: duplicateCurrentChatbot,
shortcodeParams: currentChatbot,
updateShortcodeParams: updateChatbotParams
}))), chatbotSelect === 'tabs' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoTabs, {
inversed: true,
onChange: onChangeTab,
currentTab: currentKey,
action: /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
rounded: true,
className: "secondary",
icon: "plus",
disabled: isBusy,
onClick: () => addNewChatbot()
})
}, Object.entries(keyToBotId).map(([key, botId]) => {
const chatbotParams = chatbots.find(c => c.botId === botId);
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoTab, {
key: key,
title: chatbotParams.name,
busy: busyAction
}, /*#__PURE__*/React.createElement(_app_screens_chatbots_Params__WEBPACK_IMPORTED_MODULE_14__["default"], {
options: options,
themes: themes,
defaultChatbot: defaultChatbot,
deleteCurrentChatbot: deleteCurrentChatbot,
resetCurrentChatbot: resetCurrentChatbot,
duplicateCurrentChatbot: duplicateCurrentChatbot,
shortcodeParams: chatbotParams,
updateShortcodeParams: updateChatbotParams
}));
})))), editor === 'themes' && /*#__PURE__*/React.createElement(_app_screens_chatbots_Themes__WEBPACK_IMPORTED_MODULE_16__["default"], {
themes: themes,
options: options,
updateOption: updateOption,
currentTheme: currentTheme,
onSwitchTheme: onSwitchTheme
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoColumn, {
minimal: true,
style: {
maxWidth: '50%'
}
}, /*#__PURE__*/React.createElement("small", {
style: {
marginLeft: 15,
marginBottom: -20
}
}, "Chatbot: ", /*#__PURE__*/React.createElement("b", null, currentChatbot === null || currentChatbot === void 0 ? void 0 : currentChatbot.name), " - Theme: ", /*#__PURE__*/React.createElement("b", null, currentTheme === null || currentTheme === void 0 ? void 0 : currentTheme.name)), /*#__PURE__*/React.createElement("div", {
style: {
position: 'relative',
margin: '5px 10px 10px 10px',
minHeight: 480,
borderRadius: 5,
padding: 10,
border: '2px dashed rgb(0 0 0 / 20%)',
background: 'rgb(0 0 0 / 5%)'
}
}, !!currentChatbot && /*#__PURE__*/React.createElement(_app_chatbot_ChatbotSystem__WEBPACK_IMPORTED_MODULE_17__["default"], {
system: {
botId: currentChatbot.botId,
userData: _app_settings__WEBPACK_IMPORTED_MODULE_4__.userData,
sessionId: _app_settings__WEBPACK_IMPORTED_MODULE_4__.session,
restNonce: _app_settings__WEBPACK_IMPORTED_MODULE_4__.restNonce,
pluginUrl: _app_settings__WEBPACK_IMPORTED_MODULE_4__.pluginUrl,
restUrl: _app_settings__WEBPACK_IMPORTED_MODULE_4__.restUrl,
stream: _app_settings__WEBPACK_IMPORTED_MODULE_4__.stream,
debugMode: options === null || options === void 0 ? void 0 : options.debug_mode,
eventLogs: options === null || options === void 0 ? void 0 : options.event_logs,
typewriter: options === null || options === void 0 ? void 0 : options.chatbot_typewriter,
speech_recognition: options === null || options === void 0 ? void 0 : options.shortcode_chat_speech_recognition,
speech_synthesis: options === null || options === void 0 ? void 0 : options.shortcode_chat_speech_synthesis
},
params: currentChatbot,
theme: currentTheme,
style: currentChatbot.window || currentChatbot.fullscreen ? {
position: 'absolute'
} : {}
})), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 10,
fontSize: 11,
lineHeight: '140%',
opacity: 0.5
}
}, "This is the actual chatbot, but there might be some differences when run on your front-end, depending on your theme and the other plugins you use."))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Chatbots);
/***/ }),
/***/ "./app/js/screens/chatbots/Params.js":
/*!*******************************************!*\
!*** ./app/js/screens/chatbots/Params.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _app_components_TokensInfo__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @app/components/TokensInfo */ "./app/js/components/TokensInfo.js");
/* harmony import */ var _Shortcode__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Shortcode */ "./app/js/screens/chatbots/Shortcode.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* harmony import */ var _app_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers */ "./app/js/helpers.js");
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
// React & Vendor Libs
const {
useMemo,
useState,
useEffect,
useRef
} = wp.element;
// NekoUI
const shadowFilter = 'drop-shadow(0 0 5px rgba(0,0,0,0.1))';
const voices = ['alloy', 'ash', 'ballad', 'coral', 'echo', 'sage', 'shimmer', 'verse'];
const chatIcons = ['chat-openai.svg', 'chat-robot-1.svg', 'chat-robot-2.svg', 'chat-nyao-1.svg', 'chat-nyao-2.svg', 'chat-nyao-3.svg', 'chat-color-blue.svg', 'chat-color-green.svg', 'chat-color-red.svg', 'chat-traditional-1.svg', 'chat-traditional-2.svg', 'avatar-user.svg', 'avatar-woman-blond.svg', 'avatar-woman-indian.svg', 'avatar-woman-asian.svg', 'avatar-woman-doctor.svg', 'avatar-man-blond.svg', 'avatar-man-black.svg', 'avatar-man-sunglasses.svg', 'avatar-man-pirate.svg'];
const ChatIconSelector = ({
label,
valueName,
updateShortcodeParams,
icon
}) => {
const chatIcon = icon ? icon : 'chat-color-green.svg';
const isCustomEmoji = (0,_app_helpers__WEBPACK_IMPORTED_MODULE_0__.isEmoji)(chatIcon);
const isCustom = isCustomEmoji || (chatIcon === null || chatIcon === void 0 ? void 0 : chatIcon.startsWith('https://')) || (chatIcon === null || chatIcon === void 0 ? void 0 : chatIcon.startsWith('http://'));
const previewIcon = isCustom ? chatIcon : `${_app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl}/images/${chatIcon}`;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("label", null, label, ":")), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 0,
border: '1.5px solid #d2e4f3',
borderRadius: 5,
padding: '10px 10px 10px 10px',
background: '#f5fcff'
}
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row",
style: {
marginTop: 0
}
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexWrap: 'wrap',
alignItems: 'center'
}
}, chatIcons.map(x => /*#__PURE__*/React.createElement("div", {
key: x,
style: {
cursor: 'pointer'
},
onMouseDown: ev => ev.stopPropagation(),
onClick: ev => {
ev.stopPropagation();
updateShortcodeParams(x, valueName);
}
}, /*#__PURE__*/React.createElement("img", {
style: {
marginRight: 2,
marginBottom: 2,
filter: shadowFilter
},
width: 24,
height: 24,
src: `${_app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl}/images/${x}`
}))), /*#__PURE__*/React.createElement("div", {
style: {
width: 24,
height: 24,
border: '1px solid #d2e4f3',
background: '#f5fcff',
borderRadius: 5,
cursor: 'pointer',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
},
onMouseDown: ev => ev.stopPropagation(),
onClick: ev => {
ev.stopPropagation();
updateShortcodeParams(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.pluginUrl}/images/chat-traditional-1.svg`, valueName);
}
}, "..."))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
width: 48,
display: 'flex',
alignItems: 'end'
}
}, isCustomEmoji ? /*#__PURE__*/React.createElement("div", {
style: {
fontSize: 48,
lineHeight: '48px',
marginRight: 0,
paddingTop: 0
}
}, chatIcon) : /*#__PURE__*/React.createElement("img", {
style: {
marginRight: 0,
paddingTop: 0,
filter: shadowFilter
},
width: 48,
height: 48,
src: `${previewIcon}`
}))), isCustom && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CUSTOM_ICON, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "icon",
value: chatIcon,
onBlur: newIcon => updateShortcodeParams(newIcon, valueName),
onEnter: newIcon => updateShortcodeParams(newIcon, valueName)
})))));
};
const ChatbotParams = props => {
var _shortcodeParams$tool, _currentModel$tools2, _shortcodeParams$tool2, _currentModel$tools3, _shortcodeParams$tool3, _shortcodeParams$tool4, _currentModel$tools4, _shortcodeParams$tool5, _currentModel$tools5, _shortcodeParams$tool6, _shortcodeParams$tool7, _currentModel$tools6, _shortcodeParams$tool8, _currentModel$tools7, _shortcodeParams$tool9, _shortcodeParams$tool10, _currentModel$tools8, _shortcodeParams$tool11;
const {
themes,
shortcodeParams,
updateShortcodeParams,
defaultChatbot,
blockMode,
deleteCurrentChatbot,
resetCurrentChatbot,
duplicateCurrentChatbot,
options,
...rest
} = props;
const {
completionModels,
imageModels,
realtimeModels,
getModel
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.useModels)(options, shortcodeParams.envId || null);
const isChat = shortcodeParams.mode === 'chat' ?? 'chat';
const isAssistant = shortcodeParams.mode === 'assistant' ?? false;
const isImagesChat = shortcodeParams.mode === 'images' ?? false;
const isRealtime = shortcodeParams.mode === 'realtime' ?? false;
const isContentAware = shortcodeParams.contentAware;
const aiEnvironments = useMemo(() => {
return (options === null || options === void 0 ? void 0 : options.ai_envs) || [];
}, [options.ai_envs]);
const module_embeddings = options === null || options === void 0 ? void 0 : options.module_embeddings;
const module_orchestration = options === null || options === void 0 ? void 0 : options.module_orchestration;
const availableFunctions = (options === null || options === void 0 ? void 0 : options.functions) || [];
const functions = shortcodeParams.functions || []; // { type: 'code-engine', id: '123' }
const [busyUpdatingFunctions, setBusyUpdatingFunctions] = useState(false);
const availableMCPServers = (options === null || options === void 0 ? void 0 : options.mcp_envs) || [];
const mcpServers = shortcodeParams.mcpServers || []; // { id: 'server-id' }
const previousEnvIdRef = useRef(shortcodeParams.envId);
// Update the ref when envId changes from outside (e.g., switching chatbots)
useEffect(() => {
previousEnvIdRef.current = shortcodeParams.envId;
}, [shortcodeParams.envId]);
// Does the instructions uses the {CONTENT} placeholder
const instructionsHasContent = useMemo(() => {
return shortcodeParams.instructions && shortcodeParams.instructions.includes('{CONTENT}');
}, [shortcodeParams.instructions]);
// AI Environments
const aiEnvironment = useMemo(() => {
const freshEnvironment = aiEnvironments.find(e => e.id === shortcodeParams.envId) || null;
return freshEnvironment;
}, [aiEnvironments, shortcodeParams.envId]);
// Assistants
const allAssistants = useMemo(() => {
return (aiEnvironment === null || aiEnvironment === void 0 ? void 0 : aiEnvironment.assistants) || [];
}, [aiEnvironment]);
const assistant = useMemo(() => {
const freshAssistant = allAssistants.find(e => e.id === shortcodeParams.assistantId) || null;
return freshAssistant;
}, [allAssistants, shortcodeParams.assistantId]);
// Get the actual model being used (considering defaults)
const actualModelId = assistant ? assistant.model : shortcodeParams.model || (!shortcodeParams.envId ? options === null || options === void 0 ? void 0 : options.ai_default_model : null);
const currentModel = getModel(actualModelId);
// Embeddings
const environments = options.embeddings_envs || [];
const modelSupportsFunctions = useMemo(() => {
var _currentModel$tags;
return currentModel === null || currentModel === void 0 || (_currentModel$tags = currentModel.tags) === null || _currentModel$tags === void 0 ? void 0 : _currentModel$tags.includes('functions');
}, [currentModel]);
const modelSupportsVision = useMemo(() => {
var _currentModel$tags2;
return currentModel === null || currentModel === void 0 || (_currentModel$tags2 = currentModel.tags) === null || _currentModel$tags2 === void 0 ? void 0 : _currentModel$tags2.includes('vision');
}, [currentModel]);
const modelSupportsFiles = useMemo(() => {
var _currentModel$tags3;
return currentModel === null || currentModel === void 0 || (_currentModel$tags3 = currentModel.tags) === null || _currentModel$tags3 === void 0 ? void 0 : _currentModel$tags3.includes('files');
}, [currentModel]);
const modelSupportImage = useMemo(() => {
var _currentModel$tags4;
return currentModel === null || currentModel === void 0 || (_currentModel$tags4 = currentModel.tags) === null || _currentModel$tags4 === void 0 ? void 0 : _currentModel$tags4.includes('image');
}, [currentModel]);
const modelSupportsMCP = useMemo(() => {
var _currentModel$tags5;
const hasMCP = (currentModel === null || currentModel === void 0 || (_currentModel$tags5 = currentModel.tags) === null || _currentModel$tags5 === void 0 ? void 0 : _currentModel$tags5.includes('mcp')) || false;
return hasMCP;
}, [currentModel]);
const modelSupportsTools = useMemo(() => {
var _currentModel$tools;
return (currentModel === null || currentModel === void 0 || (_currentModel$tools = currentModel.tools) === null || _currentModel$tools === void 0 ? void 0 : _currentModel$tools.length) > 0;
}, [currentModel]);
const modelSupportsResponses = useMemo(() => {
var _currentModel$tags6;
return currentModel === null || currentModel === void 0 || (_currentModel$tags6 = currentModel.tags) === null || _currentModel$tags6 === void 0 ? void 0 : _currentModel$tags6.includes('responses');
}, [currentModel]);
const modelsForDropdown = useMemo(() => {
return isImagesChat ? imageModels : (isRealtime ? realtimeModels : completionModels) ?? [];
}, [isImagesChat, isRealtime, completionModels, imageModels, realtimeModels]);
useEffect(() => {
const newFunctions = functions.filter(x => availableFunctions.some(y => y.id === x.id));
const newMCPServers = mcpServers.filter(x => availableMCPServers.some(y => y.id === x.id));
// If some functions have been removed, well, remove them
if (newFunctions.length !== functions.length) {
console.warn("Update Params: Functions has been updated.");
updateShortcodeParams(newFunctions, 'functions');
}
// If some MCP servers have been removed, well, remove them
else if (newMCPServers.length !== mcpServers.length) {
console.warn("Update Params: MCP Servers has been updated.");
updateShortcodeParams(newMCPServers, 'mcpServers');
}
// Set the default resolution if not set
else if (modelSupportImage && !shortcodeParams.resolution) {
console.warn("Update Params: Resolution has been set.");
if (currentModel !== null && currentModel !== void 0 && currentModel.resolutions) {
const resolutions = currentModel.resolutions.map(x => x.name);
const bestResolution = resolutions.includes('1024x1024') ? '1024x1024' : resolutions[0];
updateShortcodeParams(bestResolution, 'resolution');
}
}
// Remove the resolution if not an image model
else if (!modelSupportImage && shortcodeParams.resolution) {
console.warn("Update Params: Resolution has been removed.");
updateShortcodeParams(null, 'resolution');
}
// If the model cannot be found for the current model, re set it
else if (modelSupportImage && isChat) {
console.warn("Update Params: Model has been removed.");
updateShortcodeParams(null, 'model');
}
// If it's an assistant and there is a model, remove it
else if (isAssistant && shortcodeParams.model) {
console.warn("Update Params: Model has been removed.");
updateShortcodeParams(null, 'model');
}
// If mode is not assistant but there is an assistant, remove it
else if (!isAssistant && shortcodeParams.assistantId) {
console.warn("Update Params: Assistant has been removed.");
updateShortcodeParams(null, 'assistantId');
}
// If vision is enabled but current model is not vision and not in images mode, remove it
else if (shortcodeParams.imageUpload && !modelSupportsVision && !isImagesChat) {
console.warn("Update Params: Vision has been removed.");
updateShortcodeParams(null, 'imageUpload');
}
// If fileSearch but it's not an assistant, remove it
else if (shortcodeParams.fileSearch && !isAssistant) {
console.warn("Update Params: File search has been removed.");
updateShortcodeParams(null, 'fileSearch');
}
// If there is a model but the environment is not set, remove it
else if (shortcodeParams.model && !shortcodeParams.envId) {
console.warn("Update Params: Model has been removed.");
updateShortcodeParams("", 'model');
}
// If there is an shortcodeParams.envId but the env cannot be found, remove it
else if (shortcodeParams.envId && !aiEnvironment) {
console.warn("Update Params: Environment has been removed.");
updateShortcodeParams(null, 'envId');
}
// If there is a model but it doesn't exist in the current environment, remove it
else if (shortcodeParams.model && shortcodeParams.envId && !currentModel) {
console.warn("Update Params: Model has been removed because it doesn't exist in the current environment.");
updateShortcodeParams("", 'model');
}
// If model is "None" (empty string) and a specific environment is selected, auto-select first model
// Only do this when the environment has just changed
else if (!shortcodeParams.model && shortcodeParams.envId && modelsForDropdown.length > 0 && previousEnvIdRef.current !== shortcodeParams.envId) {
console.log("Update Params: Auto-selecting first available model for the environment.");
updateShortcodeParams(modelsForDropdown[0].model, 'model');
}
// If !module_embeddings but embeddingsEnvId is set, remove it
else if (!module_embeddings && shortcodeParams.embeddingsEnvId) {
console.warn("Update Params: Embeddings environment has been removed.");
updateShortcodeParams(null, 'embeddingsEnvId');
}
// Keep functions and MCP servers even when switching to models that don't support them
// The backend engine will handle what it can support
// If has file search but assistant does not support it, remove it
else if (isAssistant && !!shortcodeParams.fileSearch && !(assistant !== null && assistant !== void 0 && assistant.has_file_search)) {
console.warn("Update Params: File search has been removed.");
updateShortcodeParams(null, 'fileSearch');
}
// If aiAvatar is not set, and aiName is not set, set aiAvatar to true
else if (!shortcodeParams.aiAvatar && !shortcodeParams.aiName) {
console.warn("Update Params: AI avatar has been set to true.");
updateShortcodeParams(true, 'aiAvatar');
}
// If userAvatar is not set, and userName is not set, set userAvatar to true
else if (!shortcodeParams.userAvatar && !shortcodeParams.userName) {
console.warn("Update Params: User avatar has been set to true.");
updateShortcodeParams(true, 'userAvatar');
}
// If guestAvatar is not set, and guestName is not set, set guestAvatar to true
else if (!shortcodeParams.guestAvatar && !shortcodeParams.guestName) {
console.warn("Update Params: Guest avatar has been set to true.");
updateShortcodeParams(true, 'guestAvatar');
}
}, [shortcodeParams, mcpServers, availableMCPServers, currentModel, modelsForDropdown]);
const updateFunctionsInAssistant = async () => {
setBusyUpdatingFunctions(true);
try {
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_5__.setAssistantFunctions)(shortcodeParams.envId, shortcodeParams.assistantId, functions);
alert('Functions have been set on the assistant.');
} catch (e) {
alert(e.message);
}
setBusyUpdatingFunctions(false);
};
const availableResolutions = useMemo(() => {
if (!modelSupportImage) return [];
if (!currentModel) return [];
if (!currentModel.resolutions) {
console.error("This image model does not have resolutions.", currentModel);
return [];
}
return currentModel === null || currentModel === void 0 ? void 0 : currentModel.resolutions;
}, [currentModel, modelSupportImage]);
const titleChatbotCategory = useMemo(() => {
const type = isChat ? 'Chat' : isAssistant ? 'Assistant' : isImagesChat ? 'Images' : isRealtime ? 'Realtime' : null;
const id = (shortcodeParams === null || shortcodeParams === void 0 ? void 0 : shortcodeParams.botId) || (defaultChatbot === null || defaultChatbot === void 0 ? void 0 : defaultChatbot.id) || 'default';
// Build an array of items, filter out empty, then join with comma
const info = [type, id].filter(Boolean).join(', ');
return /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CHATBOT, /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, " ", info));
}, [isChat, isAssistant, shortcodeParams === null || shortcodeParams === void 0 ? void 0 : shortcodeParams.botId, defaultChatbot === null || defaultChatbot === void 0 ? void 0 : defaultChatbot.id]);
const titleAIModelCategory = useMemo(() => {
// Helper to build the string for a given env and model
const getDisplay = (envId, modelName) => {
const env = aiEnvironments.find(x => x.id === envId);
if (!env) return null;
const model = getModel(modelName);
return [env.name, model === null || model === void 0 ? void 0 : model.rawName].filter(Boolean).join(', ');
};
if (shortcodeParams.envId) {
const extras = getDisplay(shortcodeParams.envId, shortcodeParams.model);
if (extras) {
return /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AI_MODEL, /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, " ", extras));
}
} else {
// Fallback to default env/model
const extras = getDisplay(options === null || options === void 0 ? void 0 : options.ai_default_env, options === null || options === void 0 ? void 0 : options.ai_default_model);
if (extras) {
return /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AI_MODEL, /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, " ", extras));
}
}
// If nothing found, just return the base label
return _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AI_MODEL;
}, [shortcodeParams.envId, shortcodeParams.model, aiEnvironments, getModel, options === null || options === void 0 ? void 0 : options.ai_default_env, options === null || options === void 0 ? void 0 : options.ai_default_model]);
const titleContextCategory = useMemo(() => {
if (shortcodeParams.embeddingsEnvId) {
const env = environments.find(x => x.id === shortcodeParams.embeddingsEnvId);
if (env) {
const extras = [env.name, isContentAware ? 'Content Aware' : null].filter(Boolean).join(', ');
return /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CONTEXT, /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, " ", extras));
}
}
return _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CONTEXT;
}, [shortcodeParams.embeddingsEnvId, environments, isContentAware]);
const titleFunctionsCategory = useMemo(() => {
const baseTitle = _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FUNCTIONS;
const hasEnabledFunctions = functions.length > 0;
const countString = hasEnabledFunctions ? `Enabled: ${functions.length}, Total: ${availableFunctions.length}` : '';
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: '8px'
}
}, /*#__PURE__*/React.createElement("span", null, baseTitle), countString && /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, countString), !modelSupportsFunctions && hasEnabledFunctions && /*#__PURE__*/React.createElement("small", {
style: {
color: '#ff6b6b',
fontWeight: 'bold'
}
}, "(Not Supported)"));
}, [functions, availableFunctions, modelSupportsFunctions]);
const titleMCPServersCategory = useMemo(() => {
const baseTitle = _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MCP_SERVERS;
const hasEnabledServers = mcpServers.length > 0;
const countString = hasEnabledServers ? `Enabled: ${mcpServers.length}, Total: ${availableMCPServers.length}` : '';
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: '8px'
}
}, /*#__PURE__*/React.createElement("span", null, baseTitle), countString && /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, countString), !modelSupportsMCP && hasEnabledServers && /*#__PURE__*/React.createElement("small", {
style: {
color: '#ff6b6b',
fontWeight: 'bold'
}
}, "(Not Supported)"));
}, [mcpServers, availableMCPServers, modelSupportsMCP]);
const titleToolsCategory = useMemo(() => {
const tools = shortcodeParams.tools || [];
const availableTools = (currentModel === null || currentModel === void 0 ? void 0 : currentModel.tools) || [];
const baseTitle = _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.TOOLS || 'Tools';
const hasEnabledTools = tools.length > 0;
// Count how many enabled tools are supported by current model
const supportedCount = tools.filter(tool => availableTools.includes(tool)).length;
const unsupportedCount = tools.length - supportedCount;
const countString = hasEnabledTools ? `Enabled: ${tools.length}` : '';
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: '8px'
}
}, /*#__PURE__*/React.createElement("span", null, baseTitle), countString && /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, countString), unsupportedCount > 0 && /*#__PURE__*/React.createElement("small", {
style: {
color: '#ff6b6b',
fontWeight: 'bold'
}
}, "(Not Supported: ", unsupportedCount, ")"));
}, [shortcodeParams.tools, currentModel]);
const titleThresholdsCategory = useMemo(() => {
const contextMaxLength = shortcodeParams.contextMaxLength || (options === null || options === void 0 ? void 0 : options.context_max_length);
const info = [shortcodeParams.maxMessages ? `Messages: ${shortcodeParams.maxMessages}` : null, contextMaxLength ? `Context: ${contextMaxLength}` : null].filter(Boolean).join(', ');
return /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.THRESHOLDS, /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, " ", info));
}, [shortcodeParams.contextMaxLength, shortcodeParams.maxMessages, options === null || options === void 0 ? void 0 : options.context_max_length]);
const titleAppearanceCategory = useMemo(() => {
const theme = themes === null || themes === void 0 ? void 0 : themes.find(x => x.themeId === shortcodeParams.themeId);
const themeName = (theme === null || theme === void 0 ? void 0 : theme.name) || shortcodeParams.themeId;
const info = [themeName, shortcodeParams.window ? 'Popup' : null].filter(Boolean).join(', ');
return /*#__PURE__*/React.createElement("div", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.APPEARANCE, /*#__PURE__*/React.createElement("small", {
style: {
opacity: 0.5
}
}, " ", info));
}, [shortcodeParams.themeId, shortcodeParams.window, themes]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoColumn, _extends({
minimal: true
}, rest), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_7__.StyledBuilderForm, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordions, {
keepState: "chatbotParams"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleChatbotCategory
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.NAME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "name",
"data-form-type": "other",
disabled: shortcodeParams.botId === 'default',
value: shortcodeParams.name,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
style: {
display: 'block'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ID, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "botId",
type: "text",
placeholder: "Optional",
disabled: shortcodeParams.botId === 'default',
value: shortcodeParams.botId,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
style: {
display: 'block'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SCOPE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "scope",
type: "text",
placeholder: "Scope",
value: shortcodeParams.scope,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
}))), !isRealtime && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.LOCAL_MEMORY, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "localMemory",
label: "Yes",
checked: shortcodeParams.localMemory,
value: "1",
onChange: updateShortcodeParams
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
height: shortcodeParams.mode === 'chat' ? 76 : 'inherit'
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MODE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
id: "mode",
name: "mode",
value: shortcodeParams.mode,
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "chat",
label: "Chat"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "images",
label: "Images"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "assistant",
label: "Assistant",
isPro: true,
requirePro: !_app_settings__WEBPACK_IMPORTED_MODULE_1__.isRegistered
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "realtime",
label: "Realtime",
isPro: true,
requirePro: !_app_settings__WEBPACK_IMPORTED_MODULE_1__.isRegistered
}))), (isChat || isAssistant || isRealtime) && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 5
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.INSTRUCTIONS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTextArea, {
name: "instructions",
rows: 10,
textAreaStyle: {
resize: 'none'
},
value: shortcodeParams.instructions,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleAIModelCategory
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENVIRONMENT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "envId",
value: shortcodeParams.envId ?? "",
onChange: updateShortcodeParams,
description: !shortcodeParams.envId || shortcodeParams.envId === "" ? (() => {
const defaultEnv = aiEnvironments.find(env => env.id === (options === null || options === void 0 ? void 0 : options.ai_default_env));
return defaultEnv ? `→ ${defaultEnv.name}` : null;
})() : null
}, aiEnvironments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: "Default"
}))), (isChat || isImagesChat || isRealtime) && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MODEL, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
textFiltering: modelsForDropdown.length > 16,
name: "model",
disabled: !shortcodeParams.envId,
value: shortcodeParams.model || "",
onChange: updateShortcodeParams,
description: !shortcodeParams.model || shortcodeParams.model === "" ? !shortcodeParams.envId ? `→ ${options === null || options === void 0 ? void 0 : options.ai_default_model}` : null : null
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: shortcodeParams.envId ? "None" : "Default"
}), modelsForDropdown.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
})))), isAssistant && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ASSISTANT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "assistantId",
value: shortcodeParams.assistantId,
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: "None"
}), allAssistants.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))), modelSupportImage && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.RESOLUTION, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "resolution",
value: shortcodeParams.resolution,
onChange: updateShortcodeParams
}, availableResolutions.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: x.name,
value: x.name,
label: x.label
})))), (modelSupportsVision || isImagesChat) && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, isImagesChat ? _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.IMAGE_UPLOAD || 'Image Upload' : _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.VISION, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "imageUpload",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
checked: shortcodeParams.imageUpload,
value: "1",
onChange: updateShortcodeParams
})), modelSupportsFiles && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FILES, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "fileUpload",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
checked: shortcodeParams.fileUpload,
value: "1",
onChange: updateShortcodeParams
}))), (isChat || isRealtime) && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, isRealtime && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.VOICE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "voice",
value: shortcodeParams.voice,
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: "Default"
}), voices.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: x,
value: x,
label: x
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.TEMPERATURE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "temperature",
type: "number",
step: "0.1",
min: "0",
max: "1",
value: shortcodeParams.temperature,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MAX_TOKENS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "maxTokens",
type: "number",
description: /*#__PURE__*/React.createElement(_app_components_TokensInfo__WEBPACK_IMPORTED_MODULE_12__["default"], {
model: currentModel,
maxTokens: shortcodeParams.maxTokens,
onRecommendedClick: value => {
updateShortcodeParams(value, 'maxTokens');
},
style: {
fontSize: 11,
lineHeight: '8px'
}
}),
value: shortcodeParams.maxTokens,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})))), isAssistant && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ASSISTANT
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FILE_SEARCH, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "fileSearch",
disabled: !(assistant !== null && assistant !== void 0 && assistant.has_file_search),
description: (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(assistant !== null && assistant !== void 0 && assistant.has_file_search ? _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].SETTINGS.ASSISTANT_FILE_SEARCH : _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].SETTINGS.ASSISTANT_NO_FILE_SEARCH),
value: shortcodeParams.fileSearch,
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: "None"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "discussion",
label: "For Discussion"
}))))), (isChat || isAssistant) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleContextCategory
}, /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 15,
fontWeight: 'bold'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.EMBEDDINGS), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.EMBEDDINGS_ENV, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "embeddingsEnvId",
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_1__.isRegistered,
disabled: !module_embeddings || !(environments !== null && environments !== void 0 && environments.length),
value: shortcodeParams.embeddingsEnvId,
onChange: updateShortcodeParams
}, environments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: "None"
})))), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 15,
fontWeight: 'bold'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.OTHERS), isChat && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CONTENT_AWARE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "contentAware",
label: "Yes",
requirePro: true,
isPro: _app_settings__WEBPACK_IMPORTED_MODULE_1__.isRegistered,
checked: shortcodeParams.contentAware,
value: "1",
onChange: updateShortcodeParams
}))), isContentAware && !instructionsHasContent && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoMessage, {
variant: "danger",
style: {
marginTop: 15,
padding: '10px 15px'
}
}, /*#__PURE__*/React.createElement("p", null, (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].SETTINGS.ALERT_CONTENTAWARE_BUT_NO_CONTENT)))), (modelSupportsFunctions || functions.length > 0) && availableFunctions.length > 0 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleFunctionsCategory
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.OpenAiIcon, {
style: {
marginRight: 3
}
}), /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.AnthropicIcon, {
style: {
marginRight: 3
}
}), /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.GoogleIcon, {
style: {
marginRight: 5
}
}), (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.FUNCTIONS)), !(availableFunctions !== null && availableFunctions !== void 0 && availableFunctions.length) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoMessage, {
variant: "danger"
}, (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.FUNCTIONS_UNAVAILABLE)), !!(availableFunctions !== null && availableFunctions !== void 0 && availableFunctions.length) && /*#__PURE__*/React.createElement("div", {
style: {
maxHeight: 200,
overflowY: 'auto',
border: '1px solid #d1e3f2',
marginTop: 10,
padding: '5px 6px',
borderRadius: 5
}
}, availableFunctions === null || availableFunctions === void 0 ? void 0 : availableFunctions.map(func => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
key: func.id,
name: "functions",
label: /*#__PURE__*/React.createElement(React.Fragment, null, func.target === 'js' && /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.JsIcon, {
style: {
marginRight: 5
}
}), func.target !== 'js' && /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.PhpIcon, {
style: {
marginRight: 5
}
}), /*#__PURE__*/React.createElement("span", null, func.name)),
description: func.desc,
checked: functions.some(x => x.id === func.id),
value: func.id,
onChange: value => {
const newFunctions = functions.filter(x => x.id !== func.id);
// Type can be 'code-engine' or anything else
if (value) newFunctions.push({
type: func.type,
id: func.id
});
updateShortcodeParams(newFunctions, 'functions');
}
}))), isAssistant && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "Assistant needs to be updated with the set of functions every time you modify them (including their names, arguments, descriptions, etc)."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoButton, {
className: "primary",
fullWidth: true,
onClick: updateFunctionsInAssistant,
isBusy: busyUpdatingFunctions
}, "Set Functions on Assistant"))), (modelSupportsMCP || mcpServers.length > 0) && module_orchestration && availableMCPServers.length > 0 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleMCPServersCategory
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.AnthropicIcon, {
style: {
marginRight: 5
}
}), (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.MCP_SERVERS || 'MCP (Model Context Protocol) servers enable AI models to interact with external tools and systems.')), !(availableMCPServers !== null && availableMCPServers !== void 0 && availableMCPServers.length) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoMessage, {
variant: "danger"
}, (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.MCP_SERVERS_UNAVAILABLE || 'No MCP servers are available. Configure them in the MCP Servers section under Orchestration.')), !!(availableMCPServers !== null && availableMCPServers !== void 0 && availableMCPServers.length) && /*#__PURE__*/React.createElement("div", {
style: {
maxHeight: 200,
overflowY: 'auto',
border: '1px solid #d1e3f2',
marginTop: 10,
padding: '5px 6px',
borderRadius: 5
}
}, availableMCPServers === null || availableMCPServers === void 0 ? void 0 : availableMCPServers.map(server => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
key: server.id,
name: "mcpServers",
label: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.AnthropicIcon, {
style: {
marginRight: 5
}
}), /*#__PURE__*/React.createElement("span", null, server.name)),
description: server.url || 'MCP Server',
checked: mcpServers.some(x => x.id === server.id),
value: server.id,
onChange: value => {
const newMCPServers = mcpServers.filter(x => x.id !== server.id);
if (value) newMCPServers.push({
id: server.id
});
updateShortcodeParams(newMCPServers, 'mcpServers');
}
})))), (modelSupportsTools || ((_shortcodeParams$tool = shortcodeParams.tools) === null || _shortcodeParams$tool === void 0 ? void 0 : _shortcodeParams$tool.length) > 0) && ((currentModel === null || currentModel === void 0 || (_currentModel$tools2 = currentModel.tools) === null || _currentModel$tools2 === void 0 ? void 0 : _currentModel$tools2.length) > 0 || ((_shortcodeParams$tool2 = shortcodeParams.tools) === null || _shortcodeParams$tool2 === void 0 ? void 0 : _shortcodeParams$tool2.length) > 0) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleToolsCategory
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.OpenAiIcon, {
style: {
marginRight: 3
}
}), /*#__PURE__*/React.createElement(_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.GoogleIcon, {
style: {
marginRight: 5
}
}), (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_13__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.TOOLS || 'Enable AI tools like web search and image generation to enhance your chatbot capabilities.')), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10
}
}, ((currentModel === null || currentModel === void 0 || (_currentModel$tools3 = currentModel.tools) === null || _currentModel$tools3 === void 0 ? void 0 : _currentModel$tools3.includes('web_search')) || ((_shortcodeParams$tool3 = shortcodeParams.tools) === null || _shortcodeParams$tool3 === void 0 ? void 0 : _shortcodeParams$tool3.includes('web_search'))) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "tools_web_search",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.WEB_SEARCH || 'Web Search',
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.WEB_SEARCH || 'Allow the AI to search the web for current information',
checked: (_shortcodeParams$tool4 = shortcodeParams.tools) === null || _shortcodeParams$tool4 === void 0 ? void 0 : _shortcodeParams$tool4.includes('web_search'),
value: "web_search",
variant: !(currentModel !== null && currentModel !== void 0 && (_currentModel$tools4 = currentModel.tools) !== null && _currentModel$tools4 !== void 0 && _currentModel$tools4.includes('web_search')) && (_shortcodeParams$tool5 = shortcodeParams.tools) !== null && _shortcodeParams$tool5 !== void 0 && _shortcodeParams$tool5.includes('web_search') ? 'danger' : undefined,
onChange: value => {
const tools = shortcodeParams.tools || [];
const newTools = value ? [...tools.filter(t => t !== 'web_search'), 'web_search'] : tools.filter(t => t !== 'web_search');
updateShortcodeParams(newTools, 'tools');
}
}), ((currentModel === null || currentModel === void 0 || (_currentModel$tools5 = currentModel.tools) === null || _currentModel$tools5 === void 0 ? void 0 : _currentModel$tools5.includes('image_generation')) || ((_shortcodeParams$tool6 = shortcodeParams.tools) === null || _shortcodeParams$tool6 === void 0 ? void 0 : _shortcodeParams$tool6.includes('image_generation'))) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "tools_image_generation",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.IMAGE_GENERATION || 'Image Generation',
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.IMAGE_GENERATION || 'Allow the AI to generate images based on text descriptions',
checked: (_shortcodeParams$tool7 = shortcodeParams.tools) === null || _shortcodeParams$tool7 === void 0 ? void 0 : _shortcodeParams$tool7.includes('image_generation'),
value: "image_generation",
variant: !(currentModel !== null && currentModel !== void 0 && (_currentModel$tools6 = currentModel.tools) !== null && _currentModel$tools6 !== void 0 && _currentModel$tools6.includes('image_generation')) && (_shortcodeParams$tool8 = shortcodeParams.tools) !== null && _shortcodeParams$tool8 !== void 0 && _shortcodeParams$tool8.includes('image_generation') ? 'danger' : undefined,
onChange: value => {
const tools = shortcodeParams.tools || [];
const newTools = value ? [...tools.filter(t => t !== 'image_generation'), 'image_generation'] : tools.filter(t => t !== 'image_generation');
updateShortcodeParams(newTools, 'tools');
}
}), ((currentModel === null || currentModel === void 0 || (_currentModel$tools7 = currentModel.tools) === null || _currentModel$tools7 === void 0 ? void 0 : _currentModel$tools7.includes('thinking')) || ((_shortcodeParams$tool9 = shortcodeParams.tools) === null || _shortcodeParams$tool9 === void 0 ? void 0 : _shortcodeParams$tool9.includes('thinking'))) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "tools_thinking",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.THINKING || 'Thinking',
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.THINKING || 'Enable enhanced reasoning mode for complex tasks requiring step-by-step analysis and planning',
checked: (_shortcodeParams$tool10 = shortcodeParams.tools) === null || _shortcodeParams$tool10 === void 0 ? void 0 : _shortcodeParams$tool10.includes('thinking'),
value: "thinking",
variant: !(currentModel !== null && currentModel !== void 0 && (_currentModel$tools8 = currentModel.tools) !== null && _currentModel$tools8 !== void 0 && _currentModel$tools8.includes('thinking')) && (_shortcodeParams$tool11 = shortcodeParams.tools) !== null && _shortcodeParams$tool11 !== void 0 && _shortcodeParams$tool11.includes('thinking') ? 'danger' : undefined,
onChange: value => {
const tools = shortcodeParams.tools || [];
const newTools = value ? [...tools.filter(t => t !== 'thinking'), 'thinking'] : tools.filter(t => t !== 'thinking');
updateShortcodeParams(newTools, 'tools');
}
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleThresholdsCategory
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.INPUT_MAX_LENGTH, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "textInputMaxLength",
type: "number",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.INPUT_MAX_LENGTH,
step: "1",
min: "8",
value: shortcodeParams.textInputMaxLength,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), !isRealtime && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MAX_MESSAGES, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "maxMessages",
type: "number",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.MAX_MESSAGES,
step: "1",
min: "1",
max: "1024",
value: shortcodeParams.maxMessages,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CONTEXT_MAX_LENGTH, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "contextMaxLength",
type: "number",
step: "1",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.CONTEXT_MAX_LENGTH,
value: shortcodeParams.contextMaxLength || (options === null || options === void 0 ? void 0 : options.context_max_length),
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: titleAppearanceCategory
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.THEME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "themeId",
value: shortcodeParams.themeId,
description: "",
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "none",
label: "None"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "chatgpt",
label: "ChatGPT"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "timeless",
label: "Timeless"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "messages",
label: "Messages"
}), themes === null || themes === void 0 ? void 0 : themes.filter(x => x.type === 'css').map(theme => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: theme.themeId,
value: theme.themeId,
label: theme.name
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.POPUP, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "window",
label: "Yes",
checked: shortcodeParams.window,
value: "1",
onChange: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FULL_SCREEN, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "fullscreen",
label: "Yes",
checked: shortcodeParams.fullscreen,
value: "1",
onChange: updateShortcodeParams,
disabled: shortcodeParams.window
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.COPY_BUTTON, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "copyButton",
label: "Yes",
checked: shortcodeParams.copyButton,
value: "1",
onChange: updateShortcodeParams
}))), shortcodeParams.themeId === 'timeless' && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HEADER_SUBTITLE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "headerSubtitle",
"data-form-type": "other",
value: shortcodeParams.headerSubtitle,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AVATAR, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "aiAvatar",
label: "Yes",
checked: shortcodeParams.aiAvatar,
value: "1",
onChange: updateShortcodeParams,
disabled: !shortcodeParams.aiName
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AI_NAME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "aiName",
"data-form-type": "other",
value: shortcodeParams.aiName,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 7
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.START_SENTENCE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTextArea, {
name: "startSentence",
rows: 1,
value: shortcodeParams.startSentence,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
}))), shortcodeParams.aiAvatar && /*#__PURE__*/React.createElement(ChatIconSelector, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AI_AVATAR,
updateShortcodeParams: updateShortcodeParams,
valueName: "aiAvatarUrl",
icon: shortcodeParams.aiAvatarUrl
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AVATAR, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "userAvatar",
label: "Yes",
checked: shortcodeParams.userAvatar,
value: "1",
onChange: updateShortcodeParams,
disabled: !shortcodeParams.userName
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.USER_NAME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "userName",
"data-form-type": "other",
value: shortcodeParams.userName,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.PLACEHOLDER, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "textInputPlaceholder",
value: shortcodeParams.textInputPlaceholder,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SEND, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "textSend",
value: shortcodeParams.textSend,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CLEAR, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "textClear",
value: shortcodeParams.textClear,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
}))), shortcodeParams.userAvatar && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("i", null, "The ", /*#__PURE__*/React.createElement("a", {
href: "https://gravatar.com/",
target: "_blank",
rel: "noreferrer"
}, "gravatar"), " of this user will be used as the avatar.")), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AVATAR, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "guestAvatar",
label: "Yes",
checked: shortcodeParams.guestAvatar,
value: "1",
onChange: updateShortcodeParams,
disabled: !shortcodeParams.guestName
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.GUEST_NAME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "guestName",
value: shortcodeParams.guestName,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 7
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.COMPLIANCE_TEXT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "textCompliance",
value: shortcodeParams.textCompliance,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
}))), shortcodeParams.guestAvatar && /*#__PURE__*/React.createElement(ChatIconSelector, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.GUEST_AVATAR,
updateShortcodeParams: updateShortcodeParams,
valueName: "guestAvatarUrl",
icon: shortcodeParams.guestAvatarUrl
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.POPUP,
hide: !shortcodeParams.window
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 4
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.POSITION, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "iconPosition",
value: shortcodeParams.iconPosition,
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "bottom-right",
label: "Bottom Right"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "bottom-left",
label: "Bottom Left"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "top-right",
label: "Top Right"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "top-left",
label: "Top Left"
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BUBBLE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "iconBubble",
label: "Yes",
checked: shortcodeParams.iconBubble,
value: "1",
onChange: updateShortcodeParams
}))), /*#__PURE__*/React.createElement(ChatIconSelector, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ICON,
updateShortcodeParams: updateShortcodeParams,
valueName: "icon",
icon: shortcodeParams.icon
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 4
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ICON_TEXT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "iconText",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.ICON_TEXT,
value: shortcodeParams.iconText,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ICON_TEXT_DELAY, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
name: "iconTextDelay",
type: "number",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.ICON_TEXT_DELAY ?? 1,
value: shortcodeParams.iconTextDelay,
onBlur: updateShortcodeParams,
onEnter: updateShortcodeParams
})))), modelSupportsResponses && !isAssistant && !isImagesChat && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ADVANCED || "Advanced"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HISTORY_STRATEGY, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
scrolldown: true,
name: "historyStrategy",
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.HISTORY_STRATEGY,
value: shortcodeParams.historyStrategy || "",
onChange: updateShortcodeParams
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AUTOMATIC || "Automatic"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "internal",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FULL_HISTORY || "Full History"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "response_id",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.INCREMENTAL || "Incremental"
}))))), !blockMode && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SHORTCODES
}, /*#__PURE__*/React.createElement(_Shortcode__WEBPACK_IMPORTED_MODULE_16__["default"], {
currentChatbot: shortcodeParams,
style: {
marginTop: 10
}
}), shortcodeParams.botId !== 'default' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].HELP.CUSTOM_SHORTCODE), /*#__PURE__*/React.createElement(_Shortcode__WEBPACK_IMPORTED_MODULE_16__["default"], {
currentChatbot: shortcodeParams,
isCustom: true,
defaultChatbot: defaultChatbot,
style: {
marginTop: 10
}
}))), !blockMode && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ACTIONS
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoButton, {
className: "primary",
onClick: duplicateCurrentChatbot
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.DUPLICATE), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoButton, {
className: "secondary",
onClick: resetCurrentChatbot
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.RESET), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoButton, {
className: "danger",
disabled: shortcodeParams.name === 'Default',
onClick: deleteCurrentChatbot
}, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.DELETE))))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatbotParams);
/***/ }),
/***/ "./app/js/screens/chatbots/Shortcode.js":
/*!**********************************************!*\
!*** ./app/js/screens/chatbots/Shortcode.js ***!
\**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
// React & Vendor Libs
const {
useState,
useMemo
} = wp.element;
const StyledShortcode = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
pre {
display: flex;
align-items: center;
background: #f8fcff;
color: #779bb8;
margin: 0px;
padding: 3px 8px;
font-size: 13px;
border: 2px solid rgb(210 228 243);
border-radius: 5px;
font-family: system-ui;
cursor: pointer;
font-weight: 500;
}
.mwai-name {
font-style: italic;
}
.mwai-value {
color: var(--neko-green);
}
.skipped-params {
margin-top: 10px;
color: #ff4d4f;
}
`;
/**
* Sanitizes the parameter value to avoid breaking the shortcode.
*
* @param {string} value - The parameter value to sanitize.
* @returns {string} - The sanitized parameter value.
*/
const sanitizeParamValue = value => {
if (typeof value !== 'string') {
return value;
}
return value.replace(/"/g, '"').replace(/'/g, ''').replace(/\n/g, '\\n').replace(/\[/g, '[').replace(/\]/g, ']');
};
const Shortcode = ({
currentChatbot,
isCustom = false,
defaultChatbot,
...rest
}) => {
const [copyMessage, setCopyMessage] = useState(null);
const shortcodeData = useMemo(() => {
if (!currentChatbot) {
return {
shortcodeHtml: null,
shortcodeText: null,
skipped: []
};
}
let shortcode;
const params = [];
const skipped = [];
if (isCustom) {
for (const key in currentChatbot) {
const value = currentChatbot[key];
if (value === undefined || value === null || key === 'botId' || key === 'name' ||
//key === 'maxMessages' ||
value === '' || defaultChatbot && defaultChatbot[key] === value || typeof value === 'object' || Array.isArray(value) && value.length === 0) {
if (typeof value === 'object' && Array.isArray(value) && value.length !== 0) {
skipped.push(key);
}
continue;
}
const sanitizedValue = sanitizeParamValue(value);
const newKey = key.replace(/([A-Z])/g, match => `_${match.toLowerCase()}`);
params.push(`${newKey}="${sanitizedValue}"`);
}
shortcode = '[mwai_chatbot' + (params.length ? ` ${params.join(' ')}` : '') + ']';
} else {
const currentBotId = currentChatbot.botId ?? 'default';
params.push(`id="${currentBotId}"`);
shortcode = `[mwai_chatbot id="${currentBotId}"]`;
}
const jsxHTML = /*#__PURE__*/React.createElement("span", null, "[mwai_chatbot", ' ', params.map((param, index) => {
const [key, value] = param.split('=');
return /*#__PURE__*/React.createElement("span", {
key: index
}, /*#__PURE__*/React.createElement("span", {
className: "mwai-name"
}, key), "=", /*#__PURE__*/React.createElement("span", {
className: "mwai-value"
}, value), index < params.length - 1 ? ' ' : '');
}), "]");
return {
shortcodeHtml: jsxHTML,
shortcodeText: shortcode,
skipped
};
}, [currentChatbot, isCustom, defaultChatbot]);
const skippedParams = (shortcodeData === null || shortcodeData === void 0 ? void 0 : shortcodeData.skipped) ?? [];
const onClick = async () => {
if (!navigator.clipboard) {
alert('Clipboard is not enabled (only works with https).');
return;
}
await navigator.clipboard.writeText(shortcodeData.shortcodeText);
setCopyMessage('Copied!');
setTimeout(() => {
setCopyMessage(null);
}, 2000);
};
if (!currentChatbot) {
return null;
}
return /*#__PURE__*/React.createElement(StyledShortcode, rest, /*#__PURE__*/React.createElement("pre", {
onClick: onClick
}, !copyMessage && shortcodeData.shortcodeHtml, copyMessage && /*#__PURE__*/React.createElement("span", null, copyMessage)), skippedParams.length > 0 && /*#__PURE__*/React.createElement("div", {
className: "skipped-params"
}, "Skipped parameters: ", skippedParams.join(', ')));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Shortcode);
/***/ }),
/***/ "./app/js/screens/chatbots/Theme.js":
/*!******************************************!*\
!*** ./app/js/screens/chatbots/Theme.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _themes_ChatGPTTheme__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./themes/ChatGPTTheme */ "./app/js/screens/chatbots/themes/ChatGPTTheme.js");
/* harmony import */ var _themes_CustomTheme__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./themes/CustomTheme */ "./app/js/screens/chatbots/themes/CustomTheme.js");
/* harmony import */ var _themes_MessagesTheme__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./themes/MessagesTheme */ "./app/js/screens/chatbots/themes/MessagesTheme.js");
/* harmony import */ var _themes_TimelessTheme__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./themes/TimelessTheme */ "./app/js/screens/chatbots/themes/TimelessTheme.js");
// NekoUI
const Theme = props => {
const {
theme,
updateTheme,
resetTheme,
deleteTheme
} = props;
const onResetTheme = () => {
resetTheme();
};
const onUpdateSettings = (value, id) => {
const settings = {
...theme.settings,
[id]: value
};
updateTheme(settings, 'settings');
};
return /*#__PURE__*/React.createElement(React.Fragment, null, theme.type === 'internal' && theme.themeId === 'chatgpt' && /*#__PURE__*/React.createElement(_themes_ChatGPTTheme__WEBPACK_IMPORTED_MODULE_0__["default"], {
settings: theme.settings ?? [],
onUpdateSettings: onUpdateSettings
}), theme.type === 'internal' && theme.themeId === 'messages' && /*#__PURE__*/React.createElement(_themes_MessagesTheme__WEBPACK_IMPORTED_MODULE_1__["default"], {
settings: theme.settings ?? [],
onUpdateSettings: onUpdateSettings
}), theme.type === 'internal' && theme.themeId === 'timeless' && /*#__PURE__*/React.createElement(_themes_TimelessTheme__WEBPACK_IMPORTED_MODULE_2__["default"], {
settings: theme.settings ?? [],
onUpdateSettings: onUpdateSettings
}), theme.type !== 'internal' && /*#__PURE__*/React.createElement(_themes_CustomTheme__WEBPACK_IMPORTED_MODULE_3__["default"], {
theme: theme,
onUpdateTheme: updateTheme
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_6__["default"].COMMON.ACTIONS
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoButton, {
className: "secondary",
onClick: onResetTheme
}, _root_i18n__WEBPACK_IMPORTED_MODULE_6__["default"].COMMON.RESET), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoButton, {
className: "danger",
disabled: theme.type === 'internal',
onClick: deleteTheme
}, _root_i18n__WEBPACK_IMPORTED_MODULE_6__["default"].COMMON.DELETE)));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Theme);
/***/ }),
/***/ "./app/js/screens/chatbots/Themes.js":
/*!*******************************************!*\
!*** ./app/js/screens/chatbots/Themes.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* harmony import */ var _Theme__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Theme */ "./app/js/screens/chatbots/Theme.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
// React & Vendor Libs
const {
useState
} = wp.element;
// NekoUI
const Themes = props => {
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__.useQueryClient)();
const {
onSwitchTheme = () => {}
} = props;
const [busy, setBusy] = useState(false);
const {
data: themes
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_1__.useQuery)({
queryKey: ['themes'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_2__.retrieveThemes,
initialData: _app_settings__WEBPACK_IMPORTED_MODULE_3__.themes
});
const currentTheme = props.currentTheme;
const onChangeTab = (_themeIndex, attributes) => {
const theme = themes.find(x => x.themeId === attributes.key);
if (theme) {
onSwitchTheme(theme.themeId);
}
};
const updateTheme = async (value, id) => {
try {
setBusy(true);
const newParams = {
...currentTheme,
[id]: value
};
let newThemes = [...themes];
const themeIndex = newThemes.findIndex(x => x.themeId === currentTheme.themeId);
newThemes[themeIndex] = newParams;
newThemes = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_2__.updateThemes)(newThemes);
queryClient.setQueryData(['themes'], newThemes);
} catch (e) {
console.error(e);
}
setBusy(false);
};
const addNewTheme = async () => {
setBusy(true);
try {
const newThemes = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_2__.updateThemes)([...themes, {
type: 'css',
name: 'New Theme',
themeId: 'theme-' + (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_4__.randomHash)(),
settings: [],
style: ""
}]);
queryClient.setQueryData(['themes'], newThemes);
} catch (e) {
console.error(e);
}
setBusy(false);
};
const deleteCurrentTheme = async () => {
setBusy(true);
const newThemes = [...themes.filter(x => x.themeId !== currentTheme.themeId)];
const firstTheme = newThemes[0];
onSwitchTheme(firstTheme.themeId);
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_2__.updateThemes)(newThemes);
await queryClient.setQueryData(['themes'], newThemes);
setBusy(false);
};
const resetTheme = async () => {
setBusy(true);
const newThemes = [...themes];
const themeIndex = newThemes.findIndex(x => x.themeId === currentTheme.themeId);
newThemes[themeIndex] = {
type: newThemes[themeIndex].type,
name: newThemes[themeIndex].name,
themeId: newThemes[themeIndex].themeId,
settings: [],
style: ""
};
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_2__.updateThemes)(newThemes);
await queryClient.setQueryData(['themes'], newThemes);
setBusy(false);
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTabs, {
inversed: true,
onChange: onChangeTab,
currentTab: currentTheme === null || currentTheme === void 0 ? void 0 : currentTheme.themeId,
action: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
rounded: true,
className: "secondary",
icon: "plus",
onClick: addNewTheme
}))
}, themes === null || themes === void 0 ? void 0 : themes.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTab, {
key: x.themeId,
title: x.name,
busy: busy
}, /*#__PURE__*/React.createElement(_Theme__WEBPACK_IMPORTED_MODULE_7__["default"], {
theme: x,
updateTheme: updateTheme,
resetTheme: resetTheme,
deleteTheme: deleteCurrentTheme
})))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Themes);
/***/ }),
/***/ "./app/js/screens/chatbots/themes/ChatGPTTheme.js":
/*!********************************************************!*\
!*** ./app/js/screens/chatbots/themes/ChatGPTTheme.js ***!
\********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/components/NekoColorPicker */ "./app/js/components/NekoColorPicker.js");
// React & Vendor Libs
// NekoUI
const ChatGPTTheme = props => {
const {
settings,
onUpdateSettings
} = props;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_0__.StyledBuilderForm, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.SPACING, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "spacing",
name: "spacing",
value: (settings === null || settings === void 0 ? void 0 : settings.spacing) ?? '15px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BORDER_RADIUS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "borderRadius",
name: "borderRadius",
value: (settings === null || settings === void 0 ? void 0 : settings.borderRadius) ?? '10px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.FONT_SIZE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "fontSize",
name: "fontSize",
value: (settings === null || settings === void 0 ? void 0 : settings.fontSize) ?? '15px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.FONT_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "fontColor",
name: "fontColor",
value: (settings === null || settings === void 0 ? void 0 : settings.fontColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "fontColor",
name: "fontColor",
value: (settings === null || settings === void 0 ? void 0 : settings.fontColor) ?? '#FFFFFF',
onChange: onUpdateSettings
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BACK_PRIMARY_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundPrimaryColor",
name: "backgroundPrimaryColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundPrimaryColor) ?? '#454654',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundPrimaryColor",
name: "backgroundPrimaryColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundPrimaryColor) ?? '#454654',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BACK_SECONDARY_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundSecondaryColor",
name: "backgroundSecondaryColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#343541',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundSecondaryColor",
name: "backgroundSecondaryColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#343541',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.POPUP,
isCollapsed: false
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.75
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.WIDTH, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "width",
name: "width",
value: (settings === null || settings === void 0 ? void 0 : settings.width) ?? '460px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.75
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.MAX_HEIGHT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "maxHeight",
name: "maxHeight",
value: (settings === null || settings === void 0 ? void 0 : settings.maxHeight) ?? '40vh',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.AVATAR_MESSAGE_BACKGROUND_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "iconTextBackgroundColor",
name: "iconTextBackgroundColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextBackgroundColor) ?? '#343541',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "iconTextBackgroundColor",
name: "iconTextBackgroundColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextBackgroundColor) ?? '#343541',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.AVATAR_MESSAGE_FONT_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "iconTextColor",
name: "iconTextColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "iconTextColor",
name: "iconTextColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextColor) ?? '#FFFFFF',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BUBBLE_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "bubbleColor",
name: "bubbleColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.bubbleColor) ?? '#343541',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "bubbleColor",
name: "bubbleColor",
value: (settings === null || settings === void 0 ? void 0 : settings.bubbleColor) ?? '#343541',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.HEADER_BACKGROUND_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundHeaderColor",
name: "backgroundHeaderColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundHeaderColor) ?? '#343541',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundHeaderColor",
name: "backgroundHeaderColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundHeaderColor) ?? '#343541',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.HEADER_BUTTONS_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "headerButtonsColor",
name: "headerButtonsColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.headerButtonsColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "headerButtonsColor",
name: "headerButtonsColor",
value: (settings === null || settings === void 0 ? void 0 : settings.headerButtonsColor) ?? '#FFFFFF',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChatGPTTheme);
/***/ }),
/***/ "./app/js/screens/chatbots/themes/CustomTheme.js":
/*!*******************************************************!*\
!*** ./app/js/screens/chatbots/themes/CustomTheme.js ***!
\*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
// React & Vendor Libs
const {
useMemo,
useState,
useEffect
} = wp.element;
const DefaultCSS = `/* AI Engine Pro - Custom Theme CSS
This is a comprehensive starting template for creating your own chatbot theme.
Modify the CSS variables and styles below to customize your chatbot's appearance. */
/* ==========================================
CSS VARIABLES - Customize these first!
========================================== */
.mwai-THEME_ID-theme {
/* Core Spacing & Sizing */
--mwai-spacing: 15px;
--mwai-fontSize: 14px;
--mwai-lineHeight: 1.6;
--mwai-borderRadius: 10px;
--mwai-width: 350px;
--mwai-maxHeight: 600px;
/* Colors - Primary Palette */
--mwai-fontColor: #1a1a1a;
--mwai-bgPrimary: #ffffff;
--mwai-bgSecondary: #f8f9fa;
--mwai-primaryColor: #0066cc;
--mwai-primaryHover: #0052a3;
/* Message Colors */
--mwai-userBgColor: #0066cc;
--mwai-userTextColor: #ffffff;
--mwai-aiBgColor: #f1f3f5;
--mwai-aiTextColor: #1a1a1a;
/* UI Element Colors */
--mwai-borderColor: #e1e4e8;
--mwai-shadowColor: rgba(0, 0, 0, 0.1);
--mwai-headerBg: #f8f9fa;
--mwai-inputBg: #ffffff;
--mwai-buttonBg: #0066cc;
--mwai-buttonHover: #0052a3;
/* Typography */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
/* ==========================================
MAIN CONTAINER & LAYOUT
========================================== */
.mwai-THEME_ID-theme.mwai-chatbot {
font-size: var(--mwai-fontSize);
line-height: var(--mwai-lineHeight);
color: var(--mwai-fontColor);
background: var(--mwai-bgPrimary);
}
.mwai-THEME_ID-theme .mwai-content {
background: var(--mwai-bgPrimary);
border-radius: var(--mwai-borderRadius);
box-shadow: 0 2px 10px var(--mwai-shadowColor);
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
/* ==========================================
HEADER SECTION
========================================== */
.mwai-THEME_ID-theme .mwai-header {
display: none;
}
.mwai-THEME_ID-theme .mwai-header .mwai-name-text {
font-weight: 600;
flex: 1;
}
.mwai-THEME_ID-theme .mwai-header .mwai-buttons {
display: flex;
gap: 8px;
}
.mwai-THEME_ID-theme .mwai-header .mwai-close-button,
.mwai-THEME_ID-theme .mwai-header .mwai-resize-button {
background: none;
border: none;
cursor: pointer;
padding: 4px;
color: var(--mwai-fontColor);
opacity: 0.6;
transition: opacity 0.2s;
}
.mwai-THEME_ID-theme .mwai-header .mwai-close-button:hover,
.mwai-THEME_ID-theme .mwai-header .mwai-resize-button:hover {
opacity: 1;
}
/* ==========================================
CONVERSATION AREA
========================================== */
.mwai-THEME_ID-theme .mwai-body {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.mwai-THEME_ID-theme .mwai-conversation {
flex: 1;
overflow-y: auto;
padding: var(--mwai-spacing);
display: flex;
flex-direction: column;
gap: 10px;
}
/* Scrollbar Styling */
.mwai-THEME_ID-theme .mwai-conversation::-webkit-scrollbar {
width: 6px;
}
.mwai-THEME_ID-theme .mwai-conversation::-webkit-scrollbar-track {
background: transparent;
}
.mwai-THEME_ID-theme .mwai-conversation::-webkit-scrollbar-thumb {
background: var(--mwai-borderColor);
border-radius: 3px;
}
/* ==========================================
MESSAGES / REPLIES
========================================== */
.mwai-THEME_ID-theme .mwai-reply {
display: flex;
gap: 10px;
animation: mwai-fade-in 0.3s ease-in;
}
/* User Messages */
.mwai-THEME_ID-theme .mwai-reply.mwai-user {
background: var(--mwai-userBgColor);
color: var(--mwai-userTextColor);
border-radius: var(--mwai-borderRadius);
padding: 10px 15px;
}
.mwai-THEME_ID-theme .mwai-reply.mwai-user .mwai-text {
max-width: 100%;
word-wrap: break-word;
}
/* AI Messages */
.mwai-THEME_ID-theme .mwai-reply.mwai-ai {
background: var(--mwai-aiBgColor);
color: var(--mwai-aiTextColor);
border-radius: var(--mwai-borderRadius);
padding: 10px 15px;
}
.mwai-THEME_ID-theme .mwai-reply.mwai-ai .mwai-text {
max-width: 100%;
word-wrap: break-word;
}
/* System Messages */
.mwai-THEME_ID-theme .mwai-reply.mwai-system .mwai-text {
background: var(--mwai-bgSecondary);
color: var(--mwai-fontColor);
opacity: 0.8;
border-radius: var(--mwai-borderRadius);
padding: 8px 12px;
text-align: center;
font-size: 0.9em;
margin: 0 auto;
}
/* Avatar */
.mwai-THEME_ID-theme .mwai-reply .mwai-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--mwai-bgSecondary);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.mwai-THEME_ID-theme .mwai-reply .mwai-avatar img {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
}
/* Copy Button */
.mwai-THEME_ID-theme .mwai-reply-actions {
display: flex;
gap: 4px;
margin-top: 4px;
}
.mwai-THEME_ID-theme .mwai-copy-button {
background: var(--mwai-bgSecondary);
border: 1px solid var(--mwai-borderColor);
border-radius: 4px;
padding: 4px 8px;
cursor: pointer;
font-size: 12px;
color: var(--mwai-fontColor);
transition: all 0.2s;
}
.mwai-THEME_ID-theme .mwai-copy-button:hover {
background: var(--mwai-primaryColor);
color: white;
border-color: var(--mwai-primaryColor);
}
/* ==========================================
INPUT AREA
========================================== */
.mwai-THEME_ID-theme .mwai-input {
padding: var(--mwai-spacing);
border-top: 1px solid var(--mwai-borderColor);
background: var(--mwai-inputBg);
display: flex;
gap: 10px;
align-items: center;
}
.mwai-THEME_ID-theme .mwai-input-text {
flex: 1;
display: flex;
align-items: center;
background: var(--mwai-bgSecondary);
border: 1px solid var(--mwai-borderColor);
border-radius: calc(var(--mwai-borderRadius) / 2);
padding: 8px 12px;
}
.mwai-THEME_ID-theme .mwai-input-text textarea {
flex: 1;
border: none;
background: transparent;
resize: none;
outline: none;
font-family: inherit;
font-size: inherit;
line-height: 1.4;
max-height: 100px;
color: var(--mwai-fontColor);
}
/* Prevent focus outlines and selection */
.mwai-THEME_ID-theme .mwai-input-text:focus,
.mwai-THEME_ID-theme .mwai-input-text *:focus {
outline: none;
box-shadow: none;
}
.mwai-THEME_ID-theme .mwai-input:focus-within {
outline: none;
}
.mwai-THEME_ID-theme .mwai-input-text textarea::placeholder {
color: var(--mwai-fontColor);
opacity: 0.5;
}
/* Input Buttons */
.mwai-THEME_ID-theme .mwai-microphone {
background: none;
border: none;
cursor: pointer;
padding: 4px;
color: var(--mwai-fontColor);
opacity: 0.6;
transition: opacity 0.2s;
}
.mwai-THEME_ID-theme .mwai-microphone:hover {
opacity: 1;
}
/* File Upload - Minimalist */
.mwai-THEME_ID-theme .mwai-file-upload {
position: relative;
display: flex;
align-items: center;
}
.mwai-THEME_ID-theme .mwai-file-upload-icon {
width: 24px;
height: 24px;
cursor: pointer;
background: none;
border: none;
display: flex;
align-items: center;
justify-content: center;
position: relative;
color: var(--mwai-fontColor);
opacity: 0.6;
}
/* Default state - plus icon */
.mwai-THEME_ID-theme .mwai-file-upload-icon::before {
content: "+";
font-size: 20px;
font-weight: 300;
}
/* File uploaded states - checkmark */
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-image-ok::before,
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-document-ok::before {
content: "✓";
font-size: 16px;
}
/* Hover on uploaded files - show remove option */
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-image-ok:hover::before,
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-document-ok:hover::before,
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-image-del::before,
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-document-del::before {
content: "×";
font-size: 20px;
font-weight: 300;
}
/* Uploading states - minimal indicator */
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-image-up::before,
.mwai-THEME_ID-theme .mwai-file-upload-icon.mwai-document-up::before {
content: "•";
font-size: 24px;
}
/* Progress indicator - hidden for minimalism */
.mwai-THEME_ID-theme .mwai-file-upload-progress {
display: none;
}
.mwai-THEME_ID-theme .mwai-input-submit {
background: var(--mwai-buttonBg);
color: white;
border: none;
border-radius: calc(var(--mwai-borderRadius) / 2);
padding: 10px 20px;
cursor: pointer;
font-weight: 500;
transition: background 0.2s;
}
.mwai-THEME_ID-theme .mwai-input-submit:hover:not(:disabled) {
background: var(--mwai-buttonHover);
}
.mwai-THEME_ID-theme .mwai-input-submit:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* ==========================================
WINDOW MODE SPECIFIC
========================================== */
.mwai-THEME_ID-theme.mwai-window {
position: fixed;
right: 30px;
bottom: 30px;
width: var(--mwai-width);
z-index: 9999;
}
.mwai-THEME_ID-theme.mwai-window .mwai-content {
display: none;
opacity: 0;
max-height: var(--mwai-maxHeight);
transition: opacity 0.3s ease-in-out;
}
.mwai-THEME_ID-theme.mwai-window.mwai-open .mwai-content {
display: flex;
opacity: 1;
}
.mwai-THEME_ID-theme.mwai-window.mwai-open .mwai-trigger {
display: none;
}
/* Window Positions */
.mwai-THEME_ID-theme.mwai-window.mwai-bottom-left {
right: auto;
left: 30px;
}
.mwai-THEME_ID-theme.mwai-window.mwai-top-right {
top: 30px;
bottom: auto;
}
.mwai-THEME_ID-theme.mwai-window.mwai-top-left {
top: 30px;
bottom: auto;
right: auto;
left: 30px;
}
/* ==========================================
TRIGGER BUTTON
========================================== */
.mwai-THEME_ID-theme .mwai-trigger {
position: fixed;
right: 30px;
bottom: 30px;
z-index: 9999;
}
.mwai-THEME_ID-theme .mwai-trigger .mwai-icon-container {
background: var(--mwai-primaryColor);
color: white;
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 4px 12px var(--mwai-shadowColor);
transition: transform 0.2s, box-shadow 0.2s;
}
.mwai-THEME_ID-theme .mwai-trigger .mwai-icon-container:hover {
transform: scale(1.1);
box-shadow: 0 6px 16px var(--mwai-shadowColor);
}
.mwai-THEME_ID-theme .mwai-trigger .mwai-icon-text {
background: var(--mwai-bgPrimary);
color: var(--mwai-fontColor);
border: 1px solid var(--mwai-borderColor);
box-shadow: 0 2px 8px var(--mwai-shadowColor);
max-width: 200px;
font-size: 13px;
margin-bottom: 10px;
padding: 10px 15px;
border-radius: var(--mwai-borderRadius);
}
/* ==========================================
LOADING & ANIMATIONS
========================================== */
@keyframes mwai-fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.mwai-THEME_ID-theme .mwai-bouncing-dots {
display: flex;
gap: 4px;
padding: 10px;
}
.mwai-THEME_ID-theme .mwai-dot {
width: 8px;
height: 8px;
background: var(--mwai-primaryColor);
border-radius: 50%;
animation: mwai-bounce 1.4s infinite ease-in-out both;
}
.mwai-THEME_ID-theme .mwai-dot1 { animation-delay: -0.32s; }
.mwai-THEME_ID-theme .mwai-dot2 { animation-delay: -0.16s; }
.mwai-THEME_ID-theme .mwai-dot3 { animation-delay: 0; }
@keyframes mwai-bounce {
0%, 80%, 100% {
transform: scale(0);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
/* ==========================================
ERROR & SYSTEM MESSAGES
========================================== */
.mwai-THEME_ID-theme .mwai-error {
background: #fee;
color: #c33;
padding: 10px;
border-radius: var(--mwai-borderRadius);
margin: 10px;
text-align: center;
font-size: 0.9em;
}
/* ==========================================
SHORTCUTS & BLOCKS
========================================== */
.mwai-THEME_ID-theme .mwai-shortcuts {
padding: 10px;
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.mwai-THEME_ID-theme .mwai-shortcut {
background: var(--mwai-bgSecondary);
border: 1px solid var(--mwai-borderColor);
border-radius: calc(var(--mwai-borderRadius) / 2);
padding: 6px 12px;
cursor: pointer;
font-size: 0.9em;
transition: all 0.2s;
}
.mwai-THEME_ID-theme .mwai-shortcut:hover {
background: var(--mwai-primaryColor);
color: white;
border-color: var(--mwai-primaryColor);
}
/* ==========================================
RESPONSIVE & MOBILE
========================================== */
@media (max-width: 768px) {
.mwai-THEME_ID-theme.mwai-window {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.mwai-THEME_ID-theme.mwai-window .mwai-content {
max-height: 100%;
border-radius: 0;
}
.mwai-THEME_ID-theme .mwai-trigger {
right: 20px;
bottom: 20px;
}
}`;
// NekoUI
const CustomTheme = props => {
const {
theme,
onUpdateTheme
} = props;
const [css, setCss] = useState("");
useEffect(() => {
setCss(theme.style);
}, [theme]);
const isDirty = useMemo(() => {
return css !== theme.style;
}, [css, theme]);
const setDefaultCSS = () => {
const newCss = DefaultCSS.replace(/THEME_ID/g, theme.themeId);
setCss(newCss);
};
return /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_0__.StyledBuilderForm, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.NAME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
name: "name",
"data-form-type": "other",
value: theme.name,
onBlur: onUpdateTheme,
onEnter: onUpdateTheme
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
style: {
display: 'block'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.ID, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
name: "themeId",
type: "text",
placeholder: "Optional",
value: theme.themeId,
onBlur: onUpdateTheme,
onEnter: onUpdateTheme
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Custom CSS:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTextArea, {
name: "css",
value: css,
onChange: setCss,
rows: 16,
tabToSpaces: 2
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
fullWidth: true,
onClick: setDefaultCSS
}, "Default CSS"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
fullWidth: true,
onClick: () => {
onUpdateTheme(css, 'style');
},
disabled: !isDirty
}, "Apply CSS")));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CustomTheme);
/***/ }),
/***/ "./app/js/screens/chatbots/themes/MessagesTheme.js":
/*!*********************************************************!*\
!*** ./app/js/screens/chatbots/themes/MessagesTheme.js ***!
\*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/components/NekoColorPicker */ "./app/js/components/NekoColorPicker.js");
// NekoUI
const MessagesTheme = props => {
const {
settings,
onUpdateSettings
} = props;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_0__.StyledBuilderForm, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.SPACING, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "spacing",
name: "spacing",
value: (settings === null || settings === void 0 ? void 0 : settings.spacing) ?? '15px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BORDER_RADIUS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "borderRadius",
name: "borderRadius",
value: (settings === null || settings === void 0 ? void 0 : settings.borderRadius) ?? '10px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.FONT_SIZE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "fontSize",
name: "fontSize",
value: (settings === null || settings === void 0 ? void 0 : settings.fontSize) ?? '15px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.FONT_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "fontColor",
name: "fontColor",
value: (settings === null || settings === void 0 ? void 0 : settings.fontColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "fontColor",
name: "fontColor",
value: (settings === null || settings === void 0 ? void 0 : settings.fontColor) ?? '#FFFFFF',
onChange: onUpdateSettings
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BACK_PRIMARY_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundPrimaryColor",
name: "backgroundPrimaryColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundPrimaryColor) ?? '#fafafa',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundPrimaryColor",
name: "backgroundPrimaryColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundPrimaryColor) ?? '#fafafa',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BACK_USER_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundUserColor",
name: "backgroundUserColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#0084ff',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundUserColor",
name: "backgroundUserColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#0084ff',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BACK_AI_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundAiColor",
name: "backgroundAiColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#eee',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundAiColor",
name: "backgroundAiColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#eee',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BACK_AI_SECONDARY_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundAiSecondaryColor",
name: "backgroundAiSecondaryColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#ddd',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundAiSecondaryColor",
name: "backgroundAiSecondaryColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#ddd',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.POPUP,
isCollapsed: false
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.75
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.WIDTH, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "width",
name: "width",
value: (settings === null || settings === void 0 ? void 0 : settings.width) ?? '460px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.75
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.MAX_HEIGHT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "maxHeight",
name: "maxHeight",
value: (settings === null || settings === void 0 ? void 0 : settings.maxHeight) ?? '40vh',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.AVATAR_MESSAGE_BACKGROUND_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "iconTextBackgroundColor",
name: "iconTextBackgroundColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextBackgroundColor) ?? '#0084ff',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "iconTextBackgroundColor",
name: "iconTextBackgroundColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextBackgroundColor) ?? '#0084ff',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.AVATAR_MESSAGE_FONT_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "iconTextColor",
name: "iconTextColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "iconTextColor",
name: "iconTextColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextColor) ?? '#FFFFFF',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.BUBBLE_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "bubbleColor",
name: "bubbleColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.bubbleColor) ?? '#0084ff',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "bubbleColor",
name: "bubbleColor",
value: (settings === null || settings === void 0 ? void 0 : settings.bubbleColor) ?? '#0084ff',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.HEADER_BACKGROUND_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "backgroundHeaderColor",
name: "backgroundHeaderColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundHeaderColor) ?? '#0084ff',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "backgroundHeaderColor",
name: "backgroundHeaderColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundHeaderColor) ?? '#0084ff',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.HEADER_BUTTONS_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoInput, {
id: "headerButtonsColor",
name: "headerButtonsColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.headerButtonsColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_3__.NekoColorPicker, {
id: "headerButtonsColor",
name: "headerButtonsColor",
value: (settings === null || settings === void 0 ? void 0 : settings.headerButtonsColor) ?? '#FFFFFF',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MessagesTheme);
/***/ }),
/***/ "./app/js/screens/chatbots/themes/TimelessTheme.js":
/*!*********************************************************!*\
!*** ./app/js/screens/chatbots/themes/TimelessTheme.js ***!
\*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @app/components/NekoColorPicker */ "./app/js/components/NekoColorPicker.js");
// NekoUI
const TimelessTheme = props => {
const {
settings,
onUpdateSettings
} = props;
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_0__.NekoMessage, {
variant: "danger"
}, "This theme is ", /*#__PURE__*/React.createElement("b", null, "still in development"), ". The related settings will be available soon."), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_1__.StyledBuilderForm, null, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SPACING, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "spacing",
name: "spacing",
value: (settings === null || settings === void 0 ? void 0 : settings.spacing) ?? '15px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BORDER_RADIUS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "borderRadius",
name: "borderRadius",
value: (settings === null || settings === void 0 ? void 0 : settings.borderRadius) ?? '10px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.66
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FONT_SIZE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "fontSize",
name: "fontSize",
value: (settings === null || settings === void 0 ? void 0 : settings.fontSize) ?? '13px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.FONT_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "fontColor",
name: "fontColor",
value: (settings === null || settings === void 0 ? void 0 : settings.fontColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "fontColor",
name: "fontColor",
value: (settings === null || settings === void 0 ? void 0 : settings.fontColor) ?? '#FFFFFF',
onChange: onUpdateSettings
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BACK_PRIMARY_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "backgroundPrimaryColor",
name: "backgroundPrimaryColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundPrimaryColor) ?? '#fafafa',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "backgroundPrimaryColor",
name: "backgroundPrimaryColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundPrimaryColor) ?? '#fafafa',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BACK_USER_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "backgroundUserColor",
name: "backgroundUserColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#434cc5',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "backgroundUserColor",
name: "backgroundUserColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#434cc5',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BACK_AI_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "backgroundAiColor",
name: "backgroundAiColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#F1F3F7',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "backgroundAiColor",
name: "backgroundAiColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#eee',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BACK_AI_SECONDARY_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "backgroundAiSecondaryColor",
name: "backgroundAiSecondaryColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#ddd',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "backgroundAiSecondaryColor",
name: "backgroundAiSecondaryColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundSecondaryColor) ?? '#ddd',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.POPUP,
isCollapsed: false
}), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.75
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.WIDTH, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "width",
name: "width",
value: (settings === null || settings === void 0 ? void 0 : settings.width) ?? '360px',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col",
style: {
flex: 0.75
}
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MAX_HEIGHT, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "maxHeight",
name: "maxHeight",
value: (settings === null || settings === void 0 ? void 0 : settings.maxHeight) ?? '40vh',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AVATAR_MESSAGE_BACKGROUND_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "iconTextBackgroundColor",
name: "iconTextBackgroundColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextBackgroundColor) ?? '#343541',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "iconTextBackgroundColor",
name: "iconTextBackgroundColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextBackgroundColor) ?? '#343541',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.AVATAR_MESSAGE_FONT_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "iconTextColor",
name: "iconTextColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "iconTextColor",
name: "iconTextColor",
value: (settings === null || settings === void 0 ? void 0 : settings.iconTextColor) ?? '#FFFFFF',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
})))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.BUBBLE_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "bubbleColor",
name: "bubbleColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.bubbleColor) ?? '#434cc5',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "bubbleColor",
name: "bubbleColor",
value: (settings === null || settings === void 0 ? void 0 : settings.bubbleColor) ?? '#434cc5',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HEADER_BACKGROUND_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "backgroundHeaderColor",
name: "backgroundHeaderColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundHeaderColor) ?? '#434cc5',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "backgroundHeaderColor",
name: "backgroundHeaderColor",
value: (settings === null || settings === void 0 ? void 0 : settings.backgroundHeaderColor) ?? '#434cc5',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.HEADER_BUTTONS_COLOR, ":"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "headerButtonsColor",
name: "headerButtonsColor",
style: {
flex: 1
},
value: (settings === null || settings === void 0 ? void 0 : settings.headerButtonsColor) ?? '#FFFFFF',
onBlur: onUpdateSettings,
onEnter: onUpdateSettings
}), /*#__PURE__*/React.createElement(_app_components_NekoColorPicker__WEBPACK_IMPORTED_MODULE_4__.NekoColorPicker, {
id: "headerButtonsColor",
name: "headerButtonsColor",
value: (settings === null || settings === void 0 ? void 0 : settings.headerButtonsColor) ?? '#FFFFFF',
onChange: onUpdateSettings,
onEnter: onUpdateSettings
}))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (TimelessTheme);
/***/ }),
/***/ "./app/js/screens/discussions/Discussions.js":
/*!***************************************************!*\
!*** ./app/js/screens/discussions/Discussions.js ***!
\***************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var markdown_to_jsx__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! markdown-to-jsx */ "./node_modules/markdown-to-jsx/dist/index.modern.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Paging.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/table/Table.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _ExportModal__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ExportModal */ "./app/js/screens/discussions/ExportModal.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
// React & Vendor Libs
const {
useMemo,
useState,
useEffect,
useCallback
} = wp.element;
// NekoUI
// AI Engine
const StyledContext = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
font-size: 12px;
border-bottom: 1px solid black;
`;
const StyledType = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].span`
font-weight: bold;
text-transform: uppercase;
`;
const StyledEmbedding = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
font-size: 12px;
color: #bdb8b8;
background: #eeeeee;
padding: 2px 8px;
`;
const StyledMessageWrapper = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
font-size: 14px;
padding: 10px;
border: 1px solid #eaeaea;
background: #f5f5f5;
color: #333333;
word-break: break-word;
overflow-wrap: break-word;
word-wrap: break-word;
hyphens: auto;
img {
max-width: 100%;
height: auto;
}
a {
color: #333333;
text-decoration: underline;
}
a:hover {
color: #333333;
text-decoration: none;
}
blockquote {
border-left: 4px solid #dddddd;
padding-left: 10px;
margin-left: 0;
font-style: italic;
}
pre {
background: #eeeeee;
padding: 10px;
border-radius: 5px;
overflow-x: auto;
text-wrap: pretty;
}
code {
background: #eeeeee;
padding: 2px 5px;
border-radius: 5px;
}
table {
border-collapse: collapse;
width: 100%;
margin-bottom: 10px;
}
table td, table th {
border: 1px solid #dddddd;
text-align: left;
padding: 5px;
}
table tr:nth-child(even) {
background-color: #dddddd;
}
.mwai-dead-image {
color: #ab5252;
background: #ffd2d2;
padding: 8px 8px;
text-align: center;
}
`;
// Instead of a tag, write the object as raw HTML
// We should also avoid the iframe tag
const options = {
overrides: {
object: {
component: ({
children,
...props
}) => {
// Convert children and props to string to display as plain text
const textContent = `<object ${Object.keys(props).map(key => `${key}="${props[key]}"`).join(' ')}>${children}</object>`;
return textContent;
}
},
script: {
component: ({
children,
...props
}) => {
// Convert children and props to string to display as plain text
const textContent = `<script ${Object.keys(props).map(key => `${key}="${props[key]}"`).join(' ')}>${children}</script>`;
return textContent;
}
},
iframe: {
component: ({
children,
...props
}) => {
// Convert children and props to string to display as plain text
const textContent = `<iframe ${Object.keys(props).map(key => `${key}="${props[key]}"`).join(' ')}>${children}</iframe>`;
return textContent;
}
}
}
};
const StyledMessage = ({
content
}) => {
const [processedContent, setProcessedContent] = useState(content || '');
const checkImageURL = url => {
return new Promise(resolve => {
const img = new Image();
img.onload = () => resolve(true);
img.onerror = () => resolve(false);
img.src = url;
});
};
// Handle dead image URLs
const cleanMessage = async markdownContent => {
const regex = /!\[.*?\]\((.*?)\)/g;
let newContent = markdownContent;
let match;
while ((match = regex.exec(markdownContent)) !== null) {
const imageUrl = match[1];
const isImageAvailable = await checkImageURL(imageUrl);
if (!isImageAvailable) {
// Replace dead URL with a placeholder or a custom message
const placeholder = `<div class="mwai-dead-image">Image not available</div>`;
newContent = newContent.replace(match[0], placeholder);
}
}
setProcessedContent(newContent);
};
useEffect(() => {
if (content) {
cleanMessage(content);
}
}, [content]);
const renderedContent = useMemo(() => {
let out = "";
try {
out = (0,markdown_to_jsx__WEBPACK_IMPORTED_MODULE_1__.compiler)(processedContent, options);
} catch (e) {
console.error("Crash in markdown-to-jsx! Reverting to plain text.", {
e,
processedContent
});
out = processedContent;
}
return out;
}, [processedContent]);
return /*#__PURE__*/React.createElement(StyledMessageWrapper, null, renderedContent);
};
const Message = ({
message
}) => {
var _message$extra, _message$extra2, _message$extra3, _message$extra4;
const embeddings = message !== null && message !== void 0 && (_message$extra = message.extra) !== null && _message$extra !== void 0 && _message$extra.embeddings ? message === null || message === void 0 || (_message$extra2 = message.extra) === null || _message$extra2 === void 0 ? void 0 : _message$extra2.embeddings : message !== null && message !== void 0 && (_message$extra3 = message.extra) !== null && _message$extra3 !== void 0 && _message$extra3.embedding ? [message === null || message === void 0 || (_message$extra4 = message.extra) === null || _message$extra4 === void 0 ? void 0 : _message$extra4.embedding] : [];
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement(StyledContext, null, /*#__PURE__*/React.createElement(StyledType, null, message.role || message.type)), (embeddings === null || embeddings === void 0 ? void 0 : embeddings.length) > 0 && /*#__PURE__*/React.createElement(StyledEmbedding, null, embeddings.map(embedding => /*#__PURE__*/React.createElement("div", {
key: embeddings.id
}, /*#__PURE__*/React.createElement("span", null, embedding.title), " (", /*#__PURE__*/React.createElement("span", null, (embedding.score.toFixed(4) * 100).toFixed(2)), ")"))), /*#__PURE__*/React.createElement(StyledMessage, {
content: message.content || message.text
}));
};
const deleteDiscussions = async (chatIds = []) => {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_3__.apiUrl}/discussions/delete`, {
nonce: (0,_app_settings__WEBPACK_IMPORTED_MODULE_3__.getRestNonce)(),
method: 'POST',
json: {
chatIds
}
});
return res;
};
const Discussions = () => {
var _discussion$messages, _discussion$extra, _discussion$extra2, _discussion$extra3, _discussion$extra4, _discussion$extra5, _discussion$extra6, _discussion$extra7, _discussion$extra8, _discussion$extra9, _discussion$extra10;
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__.useQueryClient)();
const [modal, setModal] = useState({
type: null,
data: null
});
const [busyAction, setBusyAction] = useState(false);
const [autoRefresh, setAutoRefresh] = useState(false);
const {
data: chatbots
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.useQuery)({
queryKey: ['chatbots'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_6__.retrieveChatbots,
initialData: _app_settings__WEBPACK_IMPORTED_MODULE_3__.chatbots
});
const chatsColumns = useMemo(() => {
return [{
accessor: 'updated',
title: 'Time',
width: '95px',
sortable: true
}, {
accessor: 'user',
title: 'User',
width: '100px',
filters: {
type: 'text',
description: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].HELP.USER_FILTER
}
}, {
accessor: 'botId',
title: 'Chatbot',
width: '100px',
filters: {
type: 'select',
options: chatbots.map(x => ({
value: x.botId,
label: x.name
}))
}
}, {
accessor: 'preview',
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.PREVIEW,
width: '100%',
filters: {
type: 'text'
}
}, {
accessor: 'messages',
title: '#',
width: '45px'
}];
}, [chatbots]);
const [filters, setFilters] = useState(() => {
return chatsColumns.filter(v => v.filters).map(v => {
return {
accessor: v.accessor,
value: null
};
});
});
const [selectedIds, setSelectedIds] = useState([]);
// useQuery
const [chatsQueryParams, setChatsQueryParams] = useState({
filters: filters,
sort: {
accessor: 'updated',
by: 'desc'
},
page: 1,
limit: 10
});
const refreshDiscussions = useCallback(async () => {
const isTabActive = !document.hidden;
if (isTabActive) {
return await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.retrieveDiscussions)(chatsQueryParams);
} else {
return new Promise(() => {}); // Keep the promise pending
}
}, [chatsQueryParams]);
const {
isFetching: isFetchingChats,
data: chatsData,
error: chatsError
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.useQuery)({
queryKey: ['chats', JSON.stringify(chatsQueryParams)],
queryFn: refreshDiscussions,
refetchInterval: autoRefresh ? 1000 * 5 : null
});
useEffect(() => {
setChatsQueryParams({
...chatsQueryParams,
filters: filters
});
}, [filters]);
const chatsTotal = useMemo(() => {
return (chatsData === null || chatsData === void 0 ? void 0 : chatsData.total) || 0;
}, [chatsData]);
const chatsRows = useMemo(() => {
if (!(chatsData !== null && chatsData !== void 0 && chatsData.chats)) {
return [];
}
return chatsData.chats.sort((a, b) => new Date(b.updated) - new Date(a.updated)).map(chat => {
const messages = JSON.parse(chat.messages);
const extra = JSON.parse(chat.extra);
const formattedCreated = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.tableDateTimeFormatter)(chat.created);
const formattedUpdated = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.tableDateTimeFormatter)(chat.updated);
// We do this (the check in extra) to support the discussions data before May 18th
const user = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.tableUserIPFormatter)(chat.userId ?? (extra === null || extra === void 0 ? void 0 : extra.userId), chat.ip ?? (extra === null || extra === void 0 ? void 0 : extra.ip));
const userMessages = messages === null || messages === void 0 ? void 0 : messages.filter(m => m.role === 'user' || m.type === 'user');
const firstExchange = userMessages !== null && userMessages !== void 0 && userMessages.length ? userMessages[0].content || userMessages[0].text : '';
const lastExchange = userMessages !== null && userMessages !== void 0 && userMessages.length ? userMessages[userMessages.length - 1].content || userMessages[userMessages.length - 1].text : '';
// Find chatbot by exact botId
const foundChatbot = chatbots.find(c => c.botId === chat.botId);
// If not found, see if there's a parentBotId to use
const parentBotId = extra === null || extra === void 0 ? void 0 : extra.parentBotId;
const foundParent = parentBotId ? chatbots.find(c => c.botId === parentBotId) : null;
// Determine display name and optional override icon
let displayName;
let overrideIcon = null; // e.g. could be <Icon name="override" /> or a plain emoji
if (foundChatbot) {
// Standard (main) chatbot
displayName = foundChatbot.name;
} else if (foundParent) {
// Custom chatbot that overrides an existing one
displayName = foundParent.name;
// You could display an icon, e.g. a tool icon or something that implies override
overrideIcon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoIcon, {
icon: "tools",
height: "14",
style: {
position: 'relative',
top: 2,
marginRight: 2
},
tooltip: "Overriden Bot"
});
} else {
// Pure custom (no recognizable parent)
displayName = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoIcon, {
icon: "cog",
height: "14",
style: {
position: 'relative',
top: 2,
marginRight: 2
},
tooltip: "Custom Bot"
}), "Custom");
}
const jsxPreview = chat.title ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, chat.title), /*#__PURE__*/React.createElement("small", null, /*#__PURE__*/React.createElement("i", null, firstExchange))) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, firstExchange), /*#__PURE__*/React.createElement("small", null, lastExchange));
return {
id: chat.id,
botId: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, overrideIcon, displayName), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("small", null, chat.botId))),
user: user,
messages: (messages === null || messages === void 0 ? void 0 : messages.length) ?? 0,
preview: jsxPreview,
extra: extra.model,
created: /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'right'
}
}, formattedCreated),
updated: /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'right'
}
}, formattedUpdated)
};
});
}, [chatsData, chatbots]);
const discussion = useMemo(() => {
if ((selectedIds === null || selectedIds === void 0 ? void 0 : selectedIds.length) !== 1) {
return null;
}
const currentDiscussion = chatsData === null || chatsData === void 0 ? void 0 : chatsData.chats.find(x => x.id === selectedIds[0]);
if (!currentDiscussion) {
return null;
}
let messages = [];
let extra = {};
try {
messages = JSON.parse(currentDiscussion.messages);
extra = JSON.parse(currentDiscussion.extra);
} catch (e) {
console.error("Could not parse discussion messages or extra.", {
e,
currentDiscussion
});
}
return {
id: currentDiscussion.id,
chatId: currentDiscussion.chatId,
botId: currentDiscussion.botId,
messages: messages,
extra: extra,
created: currentDiscussion.created,
updated: currentDiscussion.updated
};
}, [selectedIds, chatsData]);
const onDeleteSelectedChats = async () => {
setBusyAction(true);
if (!selectedIds.length) {
if (!window.confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].ALERTS.ARE_YOU_SURE)) {
setBusyAction(false);
return;
}
await deleteDiscussions();
} else {
const selectedChats = chatsData === null || chatsData === void 0 ? void 0 : chatsData.chats.filter(x => selectedIds.includes(x.id));
const selectedChatIds = selectedChats.map(x => x.chatId);
await deleteDiscussions(selectedChatIds);
setSelectedIds([]);
}
await queryClient.invalidateQueries({
queryKey: ['chats']
});
queryClient.refetchQueries({
queryKey: ['chats']
});
setBusyAction(false);
};
const jsxPaging = useMemo(() => {
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'row'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoPaging, {
currentPage: chatsQueryParams.page,
limit: chatsQueryParams.limit,
onCurrentPageChanged: page => setChatsQueryParams({
...chatsQueryParams,
page
}),
total: chatsTotal,
onClick: page => {
setChatsQueryParams({
...chatsQueryParams,
page
});
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
className: "primary",
style: {
marginLeft: 5
},
onClick: () => {
setModal({
type: 'export',
data: {}
});
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.EXPORT)));
}, [chatsQueryParams, chatsTotal]);
const emptyMessage = useMemo(() => {
if (chatsError !== null && chatsError !== void 0 && chatsError.message) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoMessage, {
variant: "danger",
style: {
margin: "5px 5px"
}
}, /*#__PURE__*/React.createElement("b", null, chatsError.message), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, "Check your Console Logs and PHP Error Logs for more information."));
}
return null;
}, [chatsError]);
const formattedCreated = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.tableDateTimeFormatter)(discussion === null || discussion === void 0 ? void 0 : discussion.created);
const formattedUpdated = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.tableDateTimeFormatter)(discussion === null || discussion === void 0 ? void 0 : discussion.updated);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoColumn, {
minimal: true,
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoBlock, {
className: "primary",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.DISCUSSIONS,
action: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, !autoRefresh && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
className: "secondary",
style: {
marginLeft: 5
},
disabled: isFetchingChats,
onClick: async () => {
await queryClient.invalidateQueries({
queryKey: ['chats']
});
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.REFRESH), selectedIds.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
className: "danger",
disabled: false,
onClick: onDeleteSelectedChats
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.DELETE))))
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoTable, {
busy: !autoRefresh && isFetchingChats || busyAction,
sort: chatsQueryParams.sort,
onSortChange: (accessor, by) => {
setChatsQueryParams({
...chatsQueryParams,
sort: {
accessor,
by
}
});
},
emptyMessage: emptyMessage,
filters: filters,
onFilterChange: (accessor, value) => {
const freshFilters = [...filters.filter(x => x.accessor !== accessor), {
accessor,
value
}];
setFilters(freshFilters);
},
data: chatsError ? [] : chatsRows,
columns: chatsColumns,
selectedItems: selectedIds,
onSelectRow: id => {
if (selectedIds.length === 1 && selectedIds[0] === id) {
setSelectedIds([]);
return;
}
setSelectedIds([id]);
},
onSelect: ids => {
setSelectedIds([...selectedIds, ...ids]);
},
onUnselect: ids => {
setSelectedIds([...selectedIds.filter(x => !ids.includes(x))]);
}
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
marginTop: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
className: "danger",
disabled: selectedIds.length,
style: {
marginRight: 10
},
onClick: onDeleteSelectedChats
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.DELETE_ALL), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoCheckbox, {
name: "auto-refresh",
label: "Auto Refresh",
value: "1",
checked: autoRefresh,
style: {
width: 180
},
onChange: () => setAutoRefresh(!autoRefresh)
}), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), jsxPaging))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoColumn, {
minimal: true,
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoBlock, {
className: "primary",
title: "Selected Discussion",
action: /*#__PURE__*/React.createElement(React.Fragment, null)
}, !discussion && /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'center',
padding: 10
}
}, "No discussion selected."), discussion === null || discussion === void 0 || (_discussion$messages = discussion.messages) === null || _discussion$messages === void 0 ? void 0 : _discussion$messages.map((x, i) => /*#__PURE__*/React.createElement(Message, {
key: i,
message: x
}))), !!discussion && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoBlock, {
className: "primary",
title: "Information"
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Model"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 || (_discussion$extra = discussion.extra) === null || _discussion$extra === void 0 ? void 0 : _discussion$extra.model)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Bot ID (or Custom ID)"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 ? void 0 : discussion.botId)), (discussion === null || discussion === void 0 || (_discussion$extra2 = discussion.extra) === null || _discussion$extra2 === void 0 ? void 0 : _discussion$extra2.parentBotId) && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Parent Bot ID"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 || (_discussion$extra3 = discussion.extra) === null || _discussion$extra3 === void 0 ? void 0 : _discussion$extra3.parentBotId)), (discussion === null || discussion === void 0 || (_discussion$extra4 = discussion.extra) === null || _discussion$extra4 === void 0 ? void 0 : _discussion$extra4.context) && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Context"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 || (_discussion$extra5 = discussion.extra) === null || _discussion$extra5 === void 0 ? void 0 : _discussion$extra5.context)), (discussion === null || discussion === void 0 || (_discussion$extra6 = discussion.extra) === null || _discussion$extra6 === void 0 ? void 0 : _discussion$extra6.assistantId) && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Assistant ID"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 || (_discussion$extra7 = discussion.extra) === null || _discussion$extra7 === void 0 ? void 0 : _discussion$extra7.assistantId)), (discussion === null || discussion === void 0 || (_discussion$extra8 = discussion.extra) === null || _discussion$extra8 === void 0 ? void 0 : _discussion$extra8.threadId) && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Thread ID"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 || (_discussion$extra9 = discussion.extra) === null || _discussion$extra9 === void 0 ? void 0 : _discussion$extra9.threadId)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Chat ID"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 ? void 0 : discussion.chatId)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Session"), /*#__PURE__*/React.createElement("div", null, discussion === null || discussion === void 0 || (_discussion$extra10 = discussion.extra) === null || _discussion$extra10 === void 0 ? void 0 : _discussion$extra10.session)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Created"), /*#__PURE__*/React.createElement("div", null, formattedCreated)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontWeight: 'bold'
}
}, "Updated"), /*#__PURE__*/React.createElement("div", null, formattedUpdated))))), /*#__PURE__*/React.createElement(_ExportModal__WEBPACK_IMPORTED_MODULE_16__["default"], {
modal: modal,
setModal: setModal,
busy: busyAction
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Discussions);
/***/ }),
/***/ "./app/js/screens/discussions/ExportModal.js":
/*!***************************************************!*\
!*** ./app/js/screens/discussions/ExportModal.js ***!
\***************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! papaparse */ "./node_modules/papaparse/papaparse.min.js");
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(papaparse__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
// React & Vendor Libs
const {
useState
} = wp.element;
// NekoUI
// TODO: This is also present in Finetunes.js (exportAsJSON)
// Maybe we could move this to helpers-admin.js
function downloadAsFile(data, filename) {
const blob = new Blob([data], {
type: 'text/plain;charset=utf-8;'
});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
const ExportModal = ({
modal,
setModal
}) => {
const [busy, setBusy] = useState(false);
const [total, setTotal] = useState(0);
const [count, setCount] = useState(0);
//const modalData = modal?.data;
const exportJSON = async () => {
try {
setBusy(true);
const discussions = await retrieveAllDiscussions();
const json = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoStringify)(discussions, 2);
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
downloadAsFile(json, `discussions-${year}-${month}-${day}.json`);
setTimeout(() => {
setTotal(0);
}, 1000);
} catch (err) {
console.error(err);
alert("An error occurred while exporting discussions. Check your console.");
} finally {
setBusy(false);
}
};
const exportCSV = async () => {
try {
setBusy(true);
const discussions = await retrieveAllDiscussions();
const csv = papaparse__WEBPACK_IMPORTED_MODULE_0___default().unparse(discussions);
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
downloadAsFile(csv, `discussions-${year}-${month}-${day}.csv`);
setTimeout(() => {
setTotal(0);
}, 1000);
} catch (err) {
console.error(err);
alert("An error occurred while exporting discussions. Check your console.");
} finally {
setBusy(false);
}
};
const retrieveAllDiscussions = async () => {
let finished = false;
const params = {
page: 1,
limit: 20,
filters: {}
};
let discussions = [];
while (!finished) {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.retrieveDiscussions)(params);
if (res.chats.length < 2) {
finished = true;
}
setTotal(() => res.total);
res.chats.forEach(chat => {
chat.messages = JSON.parse(chat.messages);
chat.extra = JSON.parse(chat.extra);
});
discussions = discussions.concat(res.chats);
setCount(() => discussions.length);
params.page++;
}
return discussions;
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoModal, {
isOpen: (modal === null || modal === void 0 ? void 0 : modal.type) === 'export',
title: "Export Discussions",
onRequestClose: () => setModal(null),
okButton: {
label: "Close",
disabled: busy,
onClick: () => setModal(null)
},
customButtons: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
onClick: exportJSON,
disabled: busy
}, "Export JSON")),
content: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoProgress, {
busy: busy,
style: {
flex: 'auto'
},
value: count,
max: total
}))
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ExportModal);
/***/ }),
/***/ "./app/js/screens/embeddings/AddModifyModal.js":
/*!*****************************************************!*\
!*** ./app/js/screens/embeddings/AddModifyModal.js ***!
\*****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useState,
useEffect,
useMemo
} = wp.element;
// NekoUI
// AI Engine
const AddModifyModal = ({
modal,
busy,
setModal,
onAddEmbedding,
onModifyEmbedding
}) => {
const [embedding, setEmbedding] = useState(false);
const isBusy = busy;
useEffect(() => {
if ((modal === null || modal === void 0 ? void 0 : modal.type) === 'edit' || (modal === null || modal === void 0 ? void 0 : modal.type) === 'add') {
setEmbedding((modal === null || modal === void 0 ? void 0 : modal.data) || {});
}
}, [modal]);
const hasChanges = useMemo(() => {
var _modal$data, _modal$data2, _modal$data3, _modal$data4, _modal$data5;
if (!(modal !== null && modal !== void 0 && modal.data)) return true;
if ((modal === null || modal === void 0 || (_modal$data = modal.data) === null || _modal$data === void 0 ? void 0 : _modal$data.title) !== (embedding === null || embedding === void 0 ? void 0 : embedding.title)) return true;
if ((modal === null || modal === void 0 || (_modal$data2 = modal.data) === null || _modal$data2 === void 0 ? void 0 : _modal$data2.content) !== (embedding === null || embedding === void 0 ? void 0 : embedding.content)) return true;
if ((modal === null || modal === void 0 || (_modal$data3 = modal.data) === null || _modal$data3 === void 0 ? void 0 : _modal$data3.behavior) !== (embedding === null || embedding === void 0 ? void 0 : embedding.behavior)) return true;
if ((modal === null || modal === void 0 || (_modal$data4 = modal.data) === null || _modal$data4 === void 0 ? void 0 : _modal$data4.type) !== (embedding === null || embedding === void 0 ? void 0 : embedding.type)) return true;
if ((modal === null || modal === void 0 || (_modal$data5 = modal.data) === null || _modal$data5 === void 0 ? void 0 : _modal$data5.refId) !== (embedding === null || embedding === void 0 ? void 0 : embedding.refId)) return true;
return false;
}, [modal, embedding]);
const onModifyClick = async () => {
try {
await onModifyEmbedding(embedding);
setModal(null);
} catch (e) {
alert(e.message);
}
};
const onAddClick = async () => {
try {
await onAddEmbedding(embedding);
setModal(null);
} catch (e) {
alert(e.message);
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_0__.NekoModal, {
isOpen: (modal === null || modal === void 0 ? void 0 : modal.type) === 'edit' || (modal === null || modal === void 0 ? void 0 : modal.type) === 'add',
title: (modal === null || modal === void 0 ? void 0 : modal.type) === 'edit' ? _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.MODIFY_EMBEDDING : _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.ADD_EMBEDDING,
okButton: {
label: (modal === null || modal === void 0 ? void 0 : modal.type) === 'edit' ? _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.MODIFY_EMBEDDING : _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.ADD_EMBEDDING,
disabled: !hasChanges || busy,
isBusy: busy === 'addEmbedding',
onClick: () => {
modal.type === 'edit' ? onModifyClick() : onAddClick();
}
},
cancelButton: {
disabled: busy,
onClick: () => setModal(null)
},
onRequestClose: () => setModal(null),
content: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "A custom embedding can be a sentence, a paragraph or a whole article. When an user input is made, the AI will search for the best embedding that matches the user input and will be able to reply with more accuracy."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Title:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
value: embedding === null || embedding === void 0 ? void 0 : embedding.title,
placeholder: `Title, like "My Website Information"`,
description: "This is for your convenience only, it's not used anywhere.",
onChange: value => setEmbedding({
...embedding,
title: value
})
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Content:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTextArea, {
countable: "chars",
maxLength: 64000,
description: "The content of your embeddings that will be used by the AI if it matches the user input.",
value: embedding === null || embedding === void 0 ? void 0 : embedding.content,
onChange: value => setEmbedding({
...embedding,
content: value
})
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, null), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-between'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement("label", null, "Behavior:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSelect, {
scrolldown: true,
name: "behavior",
disabled: isBusy || true,
value: embedding === null || embedding === void 0 ? void 0 : embedding.behavior,
onChange: value => {
setEmbedding({
...embedding,
behavior: value
});
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoOption, {
value: "context",
label: "Context"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoOption, {
value: "reply",
label: "Reply"
}))), /*#__PURE__*/React.createElement("div", {
style: {
flex: 3,
marginLeft: 5
}
}, /*#__PURE__*/React.createElement("label", null, "Type:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoSelect, {
scrolldown: true,
name: "type",
disabled: isBusy || true,
value: embedding === null || embedding === void 0 ? void 0 : embedding.type,
onChange: value => {
setEmbedding({
...embedding,
type: value
});
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoOption, {
value: "manual",
label: "Manual"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoOption, {
value: "postId",
label: "Related to Post"
}))), (embedding === null || embedding === void 0 ? void 0 : embedding.type) === 'postId' && /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
marginLeft: 5
}
}, /*#__PURE__*/React.createElement("label", null, "Post ID:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
value: embedding === null || embedding === void 0 ? void 0 : embedding.refId,
disabled: true,
onChange: value => setEmbedding({
...embedding,
refId: value
})
}))))
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AddModifyModal);
/***/ }),
/***/ "./app/js/screens/embeddings/Embeddings.js":
/*!*************************************************!*\
!*** ./app/js/screens/embeddings/Embeddings.js ***!
\*************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! papaparse */ "./node_modules/papaparse/papaparse.min.js");
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(papaparse__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/toolbar/Toolbar.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Switch.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/table/Table.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Paging.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/UploadDropArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/hooks.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* harmony import */ var _AddModifyModal__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./AddModifyModal */ "./app/js/screens/embeddings/AddModifyModal.js");
/* harmony import */ var _ExportModal__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./ExportModal */ "./app/js/screens/embeddings/ExportModal.js");
/* harmony import */ var _ImportModal__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./ImportModal */ "./app/js/screens/embeddings/ImportModal.js");
/* harmony import */ var _pdfImport_modal__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./pdfImport/modal */ "./app/js/screens/embeddings/pdfImport/modal.js");
// React & Vendor Libs
const {
useState,
useMemo,
useEffect,
useRef
} = wp.element;
// NekoUI
const searchColumns = [{
accessor: 'status',
title: 'Status',
width: '90px'
}, {
accessor: 'title',
title: 'Title / Model',
sortable: false,
width: '100%'
}, {
accessor: 'type',
title: 'Ref',
sortable: false,
width: '90px'
}, {
accessor: 'score',
title: 'Score',
sortable: true,
width: '75px'
}, {
accessor: 'updated',
title: 'Updated',
sortable: false,
width: '90px'
}, {
accessor: 'actions',
title: '',
width: '110px'
}];
const queryColumns = [{
accessor: 'status',
title: 'Status',
sortable: true,
width: '90px'
}, {
accessor: 'title',
title: 'Title / Model',
sortable: false,
width: '100%'
}, {
accessor: 'type',
title: 'Ref',
sortable: true,
width: '90px'
}, {
accessor: 'updated',
title: 'Updated',
sortable: true,
width: '90px'
}, {
accessor: 'actions',
title: '',
width: '110px'
}];
// Status can be: pending, succeeded, failed, or cancelled
const StatusIcon = ({
embedding,
envName,
isDifferentModel
}) => {
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.useNekoColors)();
const includeText = true;
const {
status: embeddingStatus,
content,
error
} = embedding;
// Set status based on conditions
const status = useMemo(() => {
if (embeddingStatus === 'ok') {
if (!envName) return 'env_issue';
if (!content) return 'empty';
if (isDifferentModel) return 'warning';
}
return embeddingStatus;
}, [embeddingStatus, envName, content, isDifferentModel]);
// Set title based on status
const title = useMemo(() => {
if (status === 'orphan') {
return 'This embedding was retrieved from the Vector DB, but it has no content. Add some, or delete it.';
} else if (status === 'env_issue') {
return 'This embedding is not related to any Embeddings Environment. Make sure you have an Embeddings Environment selected, and Sync/Refresh it; it will be linked to the current environment. You can also delete it.';
} else if (status === 'empty') {
return 'This embedding has no content.';
} else if (status === 'warning') {
return 'This embedding was created with a different model. Sync will update it to use the current model.';
}
return error || null;
}, [status, error]);
// Set icon properties based on status
const {
icon,
color
} = useMemo(() => {
const statusMap = {
outdated: {
icon: 'alert',
color: colors.orange
},
ok: {
icon: 'check-circle',
color: colors.green
},
error: {
icon: 'alert',
color: colors.red
},
orphan: {
icon: 'pencil',
color: colors.orange
},
env_issue: {
icon: 'database',
color: colors.red
},
empty: {
icon: 'alert',
color: colors.orange
},
warning: {
icon: 'alert',
color: colors.orange
},
default: {
icon: 'alert',
color: colors.orange
}
};
return statusMap[status] || statusMap.default;
}, [status, colors]);
// Render the icon with text if includeText is true
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center'
},
title: title
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
icon: icon,
width: 24,
color: color,
title: title
}), includeText && /*#__PURE__*/React.createElement("span", {
style: {
textTransform: 'uppercase',
fontSize: 9,
marginLeft: 3
}
}, status));
};
const setLocalSettings = ({
environmentId
}) => {
const settings = {
environmentId: environmentId || null
};
localStorage.setItem('mwai-admin-embeddings', (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoStringify)(settings));
};
const getLocalSettings = () => {
const localSettingsJSON = localStorage.getItem('mwai-admin-embeddings');
try {
const parsedSettings = JSON.parse(localSettingsJSON);
return {
environmentId: (parsedSettings === null || parsedSettings === void 0 ? void 0 : parsedSettings.environmentId) || null
};
} catch (e) {
return {
environmentId: null
};
}
};
const Embeddings = ({
options,
updateOption
}) => {
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__.useQueryClient)();
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.useNekoColors)();
const [postType, setPostType] = useState('post');
const [busy, setBusy] = useState(false);
const [mode, setMode] = useState('edit');
const [search, setSearch] = useState(null);
const [searchInput, setSearchInput] = useState("");
const [embeddingModal, setEmbeddingModal] = useState(false);
const [selectedIds, setSelectedIds] = useState([]);
const [modal, setModal] = useState({
type: null,
data: null
});
const [debugMode, setDebugMode] = useState(null);
const [settingsUpdating, setSettingsUpdating] = useState(false);
const [importError, setImportError] = useState(null);
const [syncResults, setSyncResults] = useState(null);
const embeddingsSettings = options.embeddings || {};
const ref = useRef(null);
const allModels = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.useModels)(options, false, true);
const environments = options.embeddings_envs || [];
const [environmentId, setEnvironmentId] = useState(getLocalSettings().environmentId);
const environment = useMemo(() => {
return environments.find(e => e.id === environmentId) || null;
}, [environments, environmentId]);
const minScore = (environment === null || environment === void 0 ? void 0 : environment.min_score) >= 0 ? environment.min_score : 35;
const maxSelect = (environment === null || environment === void 0 ? void 0 : environment.max_select) >= 0 ? environment.max_select : 10;
const embeddingsModel = useMemo(() => {
if (environment !== null && environment !== void 0 && environment.ai_embeddings_override && environment !== null && environment !== void 0 && environment.ai_embeddings_env && environment !== null && environment !== void 0 && environment.ai_embeddings_model) {
return allModels.getModel(environment.ai_embeddings_model);
}
return allModels.getModel(options.ai_embeddings_default_model);
}, [environment, embeddingsSettings.model]);
const {
isLoading: isLoadingPostTypes,
data: postTypes
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__.useQuery)({
queryKey: ['postTypes'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_7__.retrievePostTypes
});
const {
isLoading: isLoadingCount,
data: postsCount
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__.useQuery)({
queryKey: ['postsCount-' + postType + '-' + (embeddingsSettings === null || embeddingsSettings === void 0 ? void 0 : embeddingsSettings.syncPostStatus) ?? 'publish'],
queryFn: () => (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.retrievePostsCount)(postType, (embeddingsSettings === null || embeddingsSettings === void 0 ? void 0 : embeddingsSettings.syncPostStatus) ?? 'publish')
});
const [queryParams, setQueryParams] = useState({
filters: {
envId: environmentId,
search,
debugMode: false
},
sort: {
accessor: 'updated',
by: 'desc'
},
page: 1,
limit: 20
});
const {
isFetching: isBusyQuerying,
data: vectorsData,
error: vectorsError
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__.useQuery)({
queryKey: ['vectors', (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoStringify)(queryParams)],
queryFn: () => (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.retrieveVectors)(queryParams),
staleTime: 5 * 60 * 1000,
// Consider data fresh for 5 minutes
gcTime: 10 * 60 * 1000 // Keep in cache for 10 minutes (formerly cacheTime)
});
const busyFetchingVectors = isBusyQuerying || busy === 'searchVectors';
const columns = mode === 'search' ? searchColumns : queryColumns;
const bulkTasks = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_8__.useNekoTasks)({
i18n: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"],
onStop: () => {
setBusy();
bulkTasks.reset();
}
});
const isBusy = busy || busyFetchingVectors || bulkTasks.isBusy || isLoadingPostTypes;
const setEmbeddingsSettings = async freshEmbeddingsSettings => {
setBusy('updateSettings');
await updateOption({
...freshEmbeddingsSettings
}, 'embeddings');
setBusy(null);
};
const isSyncEnvDifferent = useMemo(() => {
return embeddingsSettings.syncPosts && (embeddingsSettings === null || embeddingsSettings === void 0 ? void 0 : embeddingsSettings.syncPostsEnvId) !== environmentId;
}, [environmentId, embeddingsSettings]);
useEffect(() => {
if (!embeddingsSettings.syncPosts && embeddingsSettings.syncPostsEnvId) {
setEmbeddingsSettings({
...embeddingsSettings,
syncPostsEnvId: null
});
}
}, [embeddingsSettings.syncPosts]);
const syncEnv = useMemo(() => {
return environments.find(e => e.id === embeddingsSettings.syncPostsEnvId) || null;
}, [embeddingsSettings.syncPostsEnvId]);
useEffect(() => {
setQueryParams(prev => {
// Only update if values actually changed
if (prev.filters.envId === environmentId && prev.filters.search === search && prev.filters.debugMode === debugMode) {
return prev;
}
return {
...prev,
filters: {
envId: environmentId,
search,
debugMode
}
};
});
setLocalSettings({
environmentId
});
}, [environmentId, debugMode, search]);
useEffect(() => {
const freshSearch = mode === 'edit' ? null : "";
setSearch(freshSearch);
setSearchInput(freshSearch || "");
setQueryParams(prev => {
const newAccessor = mode === 'edit' ? 'created' : 'score';
// Only update if values actually changed
if (prev.filters.search === freshSearch && prev.sort.accessor === newAccessor && prev.sort.by === 'desc' && prev.page === 1 && prev.limit === 20) {
return prev;
}
return {
...prev,
filters: {
...prev.filters,
search: freshSearch
},
sort: {
accessor: newAccessor,
by: 'desc'
},
page: 1,
limit: 20
};
});
}, [mode]);
useEffect(() => {
var _embeddingsSettings$s, _embeddingsSettings$s2;
if (!(embeddingsSettings !== null && embeddingsSettings !== void 0 && (_embeddingsSettings$s = embeddingsSettings.syncPostTypes) !== null && _embeddingsSettings$s !== void 0 && _embeddingsSettings$s.length) || !(embeddingsSettings !== null && embeddingsSettings !== void 0 && (_embeddingsSettings$s2 = embeddingsSettings.syncPostStatus) !== null && _embeddingsSettings$s2 !== void 0 && _embeddingsSettings$s2.length)) {
setEmbeddingsSettings({
...embeddingsSettings,
syncPostTypes: ['post', 'page', 'product'],
syncPostStatus: ['publish']
});
}
}, [embeddingsSettings.syncPostTypes]);
const jsxAutoSyncStatus = useMemo(() => {
const styles = {
padding: '8px 15px',
textAlign: 'center'
};
if (embeddingsSettings.syncPosts && !syncEnv) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "danger",
style: styles
}, "Pick a valid environment for the sync.");
}
if (embeddingsSettings.syncPosts) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "special",
style: styles
}, "Enabled on ", /*#__PURE__*/React.createElement("b", null, syncEnv === null || syncEnv === void 0 ? void 0 : syncEnv.name));
}
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "info",
style: styles
}, "Disabled");
}, [embeddingsSettings]);
// #region Embeddings
const onSearchEnter = async () => {
setSearch(searchInput);
if (searchInput === queryParams.filters.search) {
queryClient.invalidateQueries({
queryKey: ['vectors']
});
return;
}
setQueryParams(prev => ({
...prev,
filters: {
...prev.filters,
search: searchInput
}
}));
};
const onResetSearch = async () => {
setSearch("");
setSearchInput("");
setQueryParams(prev => ({
...prev,
filters: {
...prev.filters,
search: ""
}
}));
};
const onAddEmbedding = async (inEmbedding = embeddingModal, skipBusy = false) => {
if (!skipBusy) {
setBusy('addEmbedding');
}
try {
const vector = {
...inEmbedding
};
if (!vector.envId) {
vector.envId = environment.id;
}
const freshVector = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_11__.apiUrl}/vectors/add`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_11__.restNonce,
method: 'POST',
json: {
vector
}
});
updateVectorsData(freshVector === null || freshVector === void 0 ? void 0 : freshVector.vector, true);
setEmbeddingModal(false);
// eslint-disable-next-line no-console
console.log("Embedding Added", inEmbedding);
} catch (err) {
console.error(err);
throw new Error(err.message ?? "Unknown error, check your console logs.");
} finally {
if (!skipBusy) {
setBusy(false);
}
}
return true;
};
const onModifyEmbedding = async (inEmbedding = embeddingModal, skipBusy) => {
if (!skipBusy) {
setBusy('addEmbedding');
}
try {
const vector = {
...inEmbedding
};
vector.envId = environment.id;
const freshVector = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_11__.apiUrl}/vectors/update`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_11__.restNonce,
method: 'POST',
json: {
vector
}
});
updateVectorsData(freshVector === null || freshVector === void 0 ? void 0 : freshVector.vector);
setEmbeddingModal(false);
// eslint-disable-next-line no-console
console.log("Embeddings updated.", freshVector);
} catch (err) {
console.error(err);
throw new Error(err.message ?? "Unknown error, check your console logs.");
} finally {
if (!skipBusy) {
setBusy(false);
}
}
// if (mode === 'search') {
// const embedding = {...inEmbedding};
// console.error("We should update the vectors data with the updated embeddings.");
// }
return true;
};
const onDeleteEmbedding = async (ids, skipBusy) => {
if (!skipBusy) {
setBusy('deleteEmbedding');
}
try {
await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_11__.apiUrl}/vectors/delete`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_11__.restNonce,
method: 'POST',
json: {
envId: environment.id,
ids
}
});
} catch (err) {
console.error(err);
// Ask the user if he wants to force the deletion
if (!confirm(`Got an error from the vector database:\n\n${err.message}\n\nDo you want to force the deletion locally?`)) {
throw new Error(err.message ?? "Unknown error, check your console logs.");
}
await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_11__.apiUrl}/vectors/delete`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_11__.restNonce,
method: 'POST',
json: {
envId: environment.id,
ids,
force: true
}
});
} finally {
if (!skipBusy) {
setBusy(false);
}
}
// eslint-disable-next-line no-console
console.log("Embeddings deleted.", {
ids
});
queryClient.invalidateQueries({
queryKey: ['vectors']
});
if (mode === 'search') {
console.error("We should update the vectors data with the deleted embeddings.");
}
};
const onSelectFiles = async files => {
// For each file, open with FileReader
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader = new FileReader();
const isJson = file.name.endsWith('.json');
const isJsonl = file.name.endsWith('.jsonl');
const isCsv = file.name.endsWith('.csv');
if (!isJson && !isJsonl && !isCsv) {
setImportError({
title: "Unsupported File Type",
message: `Only JSON, JSONL, and CSV files are supported. You provided: ${file.name}`,
details: "Please ensure your file has one of these extensions: .json, .jsonl, or .csv"
});
continue;
}
reader.onerror = () => {
setImportError({
title: "File Read Error",
message: `Failed to read the file: ${file.name}`,
details: "Please check if the file is accessible and not corrupted."
});
};
reader.onload = async e => {
try {
const fileContent = e.target.result;
let data = [];
let parseErrors = [];
if (isJson) {
try {
data = JSON.parse(fileContent);
if (!Array.isArray(data)) {
throw new Error("JSON file must contain an array of objects");
}
} catch (jsonError) {
setImportError({
title: "Invalid JSON Format",
message: `Failed to parse JSON file: ${file.name}`,
details: jsonError.message,
help: "Ensure your JSON file contains an array of objects with 'title' and 'content' fields.\n\nExample:\n[\n {\"title\": \"Example Title\", \"content\": \"Example content\"},\n {\"title\": \"Another Title\", \"content\": \"More content\"}\n]"
});
return;
}
} else if (isJsonl) {
const lines = fileContent.split('\n').filter(line => line.trim());
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
const line = lines[lineNum].trim();
if (!line) continue;
try {
const parsed = JSON.parse(line);
if (parsed) data.push(parsed);
} catch (e) {
parseErrors.push(`Line ${lineNum + 1}: ${e.message}`);
}
}
if (parseErrors.length > 0) {
setImportError({
title: "JSONL Parse Errors",
message: `Failed to parse some lines in JSONL file: ${file.name}`,
details: parseErrors.slice(0, 5).join('\n') + (parseErrors.length > 5 ? `\n...and ${parseErrors.length - 5} more errors` : ''),
help: "Each line in a JSONL file must be a valid JSON object with 'title' and 'content' fields.\n\nExample line:\n{\"title\": \"Example Title\", \"content\": \"Example content\"}"
});
if (data.length === 0) return;
}
} else if (isCsv) {
const resParse = papaparse__WEBPACK_IMPORTED_MODULE_0___default().parse(fileContent, {
header: true,
skipEmptyLines: true
});
if (resParse.errors.length > 0) {
const errorMessages = resParse.errors.slice(0, 5).map(err => `Row ${err.row || 'unknown'}: ${err.message}`).join('\n');
setImportError({
title: "CSV Parse Errors",
message: `Failed to parse CSV file: ${file.name}`,
details: errorMessages + (resParse.errors.length > 5 ? `\n...and ${resParse.errors.length - 5} more errors` : ''),
help: "Ensure your CSV file has headers including 'title' and 'content' columns.\n\nExample CSV format:\ntitle,content\n\"Example Title\",\"Example content\"\n\"Another Title\",\"More content\""
});
if (resParse.data.length === 0) return;
}
data = resParse.data;
// Check if CSV has required headers
if (data.length > 0) {
const headers = Object.keys(data[0]);
if (!headers.includes('title') || !headers.includes('content')) {
setImportError({
title: "Missing Required Columns",
message: "CSV file must have 'title' and 'content' columns",
details: `Found columns: ${headers.join(', ')}`,
help: "The first row of your CSV must contain column headers, including 'title' and 'content'.\n\nOptional columns: 'type', 'refId', 'refUrl'"
});
return;
}
}
}
// Validate data structure
if (!Array.isArray(data) || data.length === 0) {
setImportError({
title: "No Data Found",
message: "The file appears to be empty or contains no valid data",
details: `File: ${file.name}`,
help: "Please ensure your file contains at least one record with 'title' and 'content' fields."
});
return;
}
// Filter and validate entries
const validEntries = [];
const invalidEntries = [];
data.forEach((entry, index) => {
var _entry$title, _entry$content;
if (!entry || typeof entry !== 'object') {
invalidEntries.push(`Row ${index + 1}: Invalid data structure`);
return;
}
const title = (_entry$title = entry.title) === null || _entry$title === void 0 ? void 0 : _entry$title.toString().trim();
const content = (_entry$content = entry.content) === null || _entry$content === void 0 ? void 0 : _entry$content.toString().trim();
if (!title && !content) {
invalidEntries.push(`Row ${index + 1}: Both title and content are empty`);
} else if (!title) {
invalidEntries.push(`Row ${index + 1}: Missing title`);
} else if (!content) {
invalidEntries.push(`Row ${index + 1}: Missing content`);
} else {
validEntries.push({
title,
content,
type: entry.type || null,
refId: entry.refId || null,
refUrl: entry.refUrl || null
});
}
});
if (validEntries.length === 0) {
setImportError({
title: "No Valid Entries",
message: "No entries with both title and content were found",
details: invalidEntries.slice(0, 5).join('\n') + (invalidEntries.length > 5 ? `\n...and ${invalidEntries.length - 5} more issues` : ''),
help: "Each entry must have both a 'title' and 'content' field with non-empty values."
});
return;
}
if (invalidEntries.length > 0) {
console.warn('Import validation issues:', invalidEntries);
}
// Success - show import modal
setModal({
type: 'import',
data: {
importVectors: validEntries,
envId: environmentId,
totalEntries: data.length,
validEntries: validEntries.length,
invalidEntries: invalidEntries.length
}
});
} catch (error) {
console.error('Import error:', error);
setImportError({
title: "Import Failed",
message: "An unexpected error occurred while processing the file",
details: error.message,
help: "Please check the file format and try again. If the problem persists, check the browser console for more details."
});
}
};
reader.readAsText(file);
}
};
const deleteSelected = async () => {
if (!confirm(`Are you sure you want to delete the selected embeddings?`)) {
return;
}
setBusy('deleteEmbeddings');
await onDeleteEmbedding(selectedIds);
setSelectedIds([]);
setBusy(false);
};
const deleteAllEmbeddings = async () => {
if (!environment) {
return;
}
if (!confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.DELETE_ALL_EMBEDDINGS_CONFIRM + `\n\n${environment.name}`)) {
return;
}
setBusy('deleteAllEmbeddings');
try {
await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_11__.apiUrl}/vectors/delete_all`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_11__.restNonce,
method: 'POST',
json: {
envId: environmentId
}
});
queryClient.invalidateQueries({
queryKey: ['vectors']
});
} catch (err) {
alert((err === null || err === void 0 ? void 0 : err.message) ?? err);
}
setBusy(false);
};
const vectorsTotal = useMemo(() => {
return (vectorsData === null || vectorsData === void 0 ? void 0 : vectorsData.total) || 0;
}, [vectorsData]);
const vectorsRows = useMemo(() => {
const data = vectorsData;
if (!(data !== null && data !== void 0 && data.vectors)) {
return [];
}
return data === null || data === void 0 ? void 0 : data.vectors.map(x => {
var _environments$find;
let updated = new Date(x.updated);
updated = new Date(updated.getTime() - updated.getTimezoneOffset() * 60 * 1000);
const day = updated.toLocaleDateString('ja-JP', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
const time = updated.toLocaleTimeString('ja-JP', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
const updatedFormattedTime = /*#__PURE__*/React.createElement("span", null, day, /*#__PURE__*/React.createElement("br", null), time);
let created = new Date(x.created);
created = new Date(created.getTime() - created.getTimezoneOffset() * 60 * 1000);
const createdFormattedTime = created.toLocaleDateString('ja-JP', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
const score = x.score ? /*#__PURE__*/React.createElement("span", {
style: {
color: x.score > minScore / 100 ? 'var(--neko-green)' : 'inherit'
}
}, (x.score.toFixed(4) * 100).toFixed(2)) : '-';
let subType = null;
if (x.subType && typeof x.subType === 'string') {
subType = x.subType.toUpperCase();
}
const currentModel = allModels.getModel(x.model);
// Use rawName for display in tables (nice name without JSX tags)
const modelName = (currentModel === null || currentModel === void 0 ? void 0 : currentModel.rawName) ?? x.model;
// Use the model ID (x.model) directly for raw name to avoid formatted names
const modelRawName = x.model;
const isDifferentModel = x.model && x.model !== (embeddingsModel === null || embeddingsModel === void 0 ? void 0 : embeddingsModel.model);
const isDifferentEnv = x.envId !== environmentId;
const envName = (_environments$find = environments.find(e => e.id === x.envId)) === null || _environments$find === void 0 ? void 0 : _environments$find.name;
const needsSync = x.status !== 'ok' || isDifferentModel || isDifferentEnv;
let potentialError = null;
// If there's an error, show only [ERROR]
if (x.status === 'error' && x.error) {
let errorText = x.error;
// Clean up Pinecone/vector DB error messages
// If we have both a descriptive message and an error code, keep only the descriptive part
if (errorText.includes('Error code:')) {
// Extract just the main error message before "Error code:"
errorText = errorText.split('Error code:')[0].trim();
// Remove trailing period to avoid double periods
if (errorText.endsWith('.')) {
errorText = errorText.slice(0, -1);
}
}
potentialError = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("b", {
style: {
color: colors.red
}
}, "Error: "), /*#__PURE__*/React.createElement("span", {
style: {
color: colors.red
}
}, errorText, " "));
}
// Otherwise, check for model mismatch
else if (isDifferentModel) {
// Use raw name for expected model (without tags)
const expectedModel = allModels.getModel(embeddingsModel === null || embeddingsModel === void 0 ? void 0 : embeddingsModel.model);
const expectedModelName = (expectedModel === null || expectedModel === void 0 ? void 0 : expectedModel.rawName) || (expectedModel === null || expectedModel === void 0 ? void 0 : expectedModel.name) || (embeddingsModel === null || embeddingsModel === void 0 ? void 0 : embeddingsModel.model);
potentialError = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("b", {
style: {
color: colors.red
}
}, "Mismatch:"), " Expected ", expectedModelName, ", but found ");
console.error(`Embeddings Model Mismatch for #${x.id}: "${x.title}". Should be "${embeddingsModel === null || embeddingsModel === void 0 ? void 0 : embeddingsModel.model}" but "${x.model}" was found.`);
} else if (isDifferentEnv && envName) {
potentialError = /*#__PURE__*/React.createElement("b", {
style: {
color: colors.green
}
}, "[ENV: ", envName, "] ");
}
return {
id: x.id,
type: /*#__PURE__*/React.createElement("small", null, x.refId ? /*#__PURE__*/React.createElement(React.Fragment, null, "ID ", /*#__PURE__*/React.createElement("a", {
href: `/wp-admin/post.php?post=${x.refId}&action=edit`,
target: "_blank",
rel: "noreferrer"
}, "#", x.refId), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '80%',
marginTop: -5
}
}, subType)) : 'MANUAL'),
score: score,
title: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", null, x.title), /*#__PURE__*/React.createElement("div", {
style: {
lineHeight: '1.2',
marginTop: 2
}
}, /*#__PURE__*/React.createElement("small", {
style: {
color: isDifferentModel || x.status === 'error' ? colors.red : 'inherit'
}
}, potentialError, x.status !== 'error' && /*#__PURE__*/React.createElement(React.Fragment, null, isDifferentModel ? modelRawName : modelName, x.dimensions && /*#__PURE__*/React.createElement(React.Fragment, null, ", ", x.dimensions, " dimensions"))))),
status: /*#__PURE__*/React.createElement(StatusIcon, {
embedding: x,
envName: envName,
isDifferentModel: isDifferentModel
}),
updated: updatedFormattedTime,
created: createdFormattedTime,
actions: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "primary",
rounded: true,
icon: "pencil",
disabled: isBusy,
onClick: () => setModal({
type: 'edit',
data: x
})
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "primary",
rounded: true,
icon: "replay",
disabled: isBusy || !needsSync,
onClick: () => onSynchronizeEmbedding(x.id)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "danger",
rounded: true,
icon: "trash",
disabled: isBusy,
onClick: () => onDeleteEmbedding([x.id])
}))
};
});
}, [mode, vectorsData, isBusy]);
// #endregion
// #region Sync
const onSynchronizeEmbedding = async vectorId => {
setBusy('syncEmbedding');
try {
await runProcess(vectorId);
} catch (error) {
console.error(error);
alert((error === null || error === void 0 ? void 0 : error.message) ?? error);
}
setBusy(false);
};
const updateVectorsData = (freshVector, isAdd = false) => {
// TODO: When everything works perfectly fine in the Embeddings (add, delete, sync, etc)
// Let's try to update the vectorsData without fetching the data again.
queryClient.invalidateQueries({
queryKey: ['vectors']
});
return;
const currentVectorsData = queryClient.getQueryData(['vectors', queryParams]);
if (currentVectorsData && currentVectorsData.vectors) {
let wasUpdated = false;
let updatedVectors = currentVectorsData.vectors.map(vector => {
const isSameId = vector.id === freshVector.id;
const isSameEnvAndRefId = vector.envId === freshVector.envId && vector.refId === freshVector.refId && !!vector.refId && !!freshVector.refId;
const isSameOrphan = !!debugMode && vector.title === freshVector.title;
//console.log({ title: vector.title, freshTitle: freshVector.title, isSameId, isSameEnvAndRefId, isSameOrphan });
if (isSameId || isSameEnvAndRefId || isSameOrphan) {
wasUpdated = true;
return {
...vector,
...freshVector
};
}
return vector;
});
if (!wasUpdated && isAdd) {
updatedVectors = [freshVector, ...updatedVectors];
currentVectorsData.total += 1;
}
// Sort the updated vectors based on the accessor and sorting order
const {
accessor,
by
} = queryParams.sort;
updatedVectors.sort((a, b) => {
if (by === 'asc') {
return a[accessor] - b[accessor];
} else {
return b[accessor] - a[accessor];
}
});
// Apply pagination to the updated vectors
const {
page,
limit
} = queryParams;
const startIndex = (page - 1) * limit;
const endIndex = startIndex + limit;
const paginatedVectors = updatedVectors.slice(startIndex, endIndex);
const updatedVectorsData = {
...currentVectorsData,
vectors: paginatedVectors
};
queryClient.setQueryData(['vectors', queryParams], updatedVectorsData);
}
};
const runProcess = async (vectorId = null, postId = null, signal = undefined) => {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.synchronizeEmbedding)({
vectorId,
postId,
envId: environmentId
}, signal);
if (res.success) {
updateVectorsData(res.vector);
}
return res;
};
const onBulkPullClick = async () => {
setBusy('bulkPullAll');
const params = {
page: 1,
limit: 10000,
filters: {
envId: environmentId
}
};
let remoteVectors = [];
let vectors = [];
let finished = false;
while (!finished) {
try {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.retrieveRemoteVectors)(params);
if (res.vectors.length < params.limit) {
finished = true;
}
//setTotal(() => res.total);
remoteVectors = remoteVectors.concat(res.vectors);
//setCount(() => remoteVectors.length);
params.page++;
} catch (e) {
console.error(e);
alert((e === null || e === void 0 ? void 0 : e.message) ?? e);
setBusy(false);
return;
}
}
// eslint-disable-next-line no-console
console.log("Remote vectors retrieved.", {
remoteVectors
});
finished = false;
params.limit = 20;
params.page = 0;
while (!finished) {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.retrieveVectors)(params);
if (res.vectors.length < params.limit) {
finished = true;
}
//setTotal(() => res.total);
vectors = vectors.concat(res.vectors);
//setCount(() => vectors.length);
params.page++;
}
vectors = vectors.map(x => x.dbId);
// eslint-disable-next-line no-console
console.log("Local vectors retrieved.", {
vectors
});
const vectorsToPull = remoteVectors.filter(x => !vectors.includes(x));
// eslint-disable-next-line no-console
console.log("Vectors to pull from Vector DB to AI Engine.", {
vectorsToPull
});
if (!vectorsToPull.length) {
setBusy(false);
setSyncResults({
type: 'pull',
stats: {
total: 0,
added: 0,
errors: 0,
errorDetails: [],
remoteTotal: remoteVectors.length,
alreadySynced: vectors.length
}
});
return;
}
const syncStats = {
total: vectorsToPull.length,
added: 0,
errors: 0,
errorDetails: [],
remoteTotal: remoteVectors.length,
alreadySynced: vectors.length
};
const tasks = vectorsToPull.map(dbId => async signal => {
try {
await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.addFromRemote)({
envId: environmentId,
dbId: dbId
}, signal);
await queryClient.invalidateQueries({
queryKey: ['vectors']
});
syncStats.added++;
return {
success: true
};
} catch (error) {
syncStats.errors++;
syncStats.errorDetails.push({
dbId,
error: error.message
});
return {
success: false,
error
};
}
});
await bulkTasks.start(tasks);
setBusy(false);
setSyncResults({
type: 'pull',
stats: syncStats
});
bulkTasks.reset();
};
const onBulkPushClick = async (all = false) => {
setBusy('bulkPushAll');
let tasks = [];
const syncStats = {
total: 0,
added: 0,
updated: 0,
upToDate: 0,
skipped: 0,
errors: 0,
errorDetails: []
};
if (all || selectedIds.length === 0) {
const postIds = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.retrievePostsIds)(postType, embeddingsSettings.syncPostStatus);
syncStats.total = postIds.length;
tasks = postIds.map(postId => async signal => {
try {
const res = await runProcess(null, postId, signal);
if (res.success) {
// Use the action field from the backend
switch (res.action) {
case 'added':
syncStats.added++;
break;
case 'updated':
syncStats.updated++;
break;
case 'up-to-date':
syncStats.upToDate++;
break;
case 'skipped':
syncStats.skipped++;
break;
default:
// Fallback for old responses
if (res.message && res.message.includes("no content")) {
syncStats.skipped++;
} else if (res.vector) {
syncStats.upToDate++;
}
}
} else {
syncStats.errors++;
if (res.message) syncStats.errorDetails.push({
postId,
error: res.message
});
}
return {
success: true
};
} catch (error) {
syncStats.errors++;
syncStats.errorDetails.push({
postId,
error: error.message
});
return {
success: false,
error
};
}
});
} else {
// Selected IDs
const vectors = vectorsData.vectors.filter(x => selectedIds.includes(x.id));
syncStats.total = vectors.length;
tasks = vectors.map(vector => async signal => {
try {
let res;
if (vector.refId) {
res = await runProcess(vector.id, null, signal);
} else {
await onModifyEmbedding(vector, signal);
res = {
success: true
};
}
if (res.success) {
// Use the action field from the backend
switch (res.action) {
case 'added':
syncStats.added++;
break;
case 'updated':
syncStats.updated++;
break;
case 'up-to-date':
syncStats.upToDate++;
break;
case 'skipped':
syncStats.skipped++;
break;
default:
syncStats.upToDate++;
}
} else {
syncStats.errors++;
if (res.message) syncStats.errorDetails.push({
title: vector.title,
error: res.message
});
}
return {
success: true
};
} catch (error) {
syncStats.errors++;
syncStats.errorDetails.push({
title: vector.title,
error: error.message
});
return {
success: false,
error
};
}
});
}
await bulkTasks.start(tasks);
setBusy(false);
setSyncResults({
type: 'push',
stats: syncStats,
selectedType: all ? `All ${postType}s` : 'Selected items'
});
bulkTasks.reset();
};
const OnSingleRunClick = async () => {
const postId = prompt("Enter the Post ID to synchronize with:");
if (!postId) {
return;
}
setBusy('singleRun');
try {
await runProcess(null, postId);
} catch (error) {
console.error(error);
alert((error === null || error === void 0 ? void 0 : error.message) ?? error);
}
setBusy(false);
};
// #endregion
const jsxEnvIndexNS = useMemo(() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSelect, {
scrolldown: true,
name: "environment",
style: {
flex: 1,
marginBottom: 5
},
disabled: isBusy,
value: (environment === null || environment === void 0 ? void 0 : environment.id) ?? null,
onChange: value => {
setEnvironmentId(value);
}
}, environments.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})), !(environments !== null && environments !== void 0 && environments.length) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoOption, {
value: null,
label: "None"
})))), [environment, environments, isBusy]);
const emptyMessage = useMemo(() => {
if (vectorsError !== null && vectorsError !== void 0 && vectorsError.message) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "danger",
style: {
margin: "5px 5px"
}
}, /*#__PURE__*/React.createElement("b", null, vectorsError.message), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, "Check your Console Logs and PHP Error Logs for more information."));
}
return mode === 'search' ? _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].HELP.NO_EMBEDDINGS_RESULTS : _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].HELP.NO_EMBEDDINGS_ROWS;
}, [mode, vectorsError]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoColumn, {
fullWidth: true,
minimal: true,
style: {
margin: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoToolbar, {
style: {
flex: 1,
marginRight: 15
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSwitch, {
style: {
marginRight: 10
},
disabled: isBusy,
onLabel: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.AI_SEARCH,
offLabel: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.EDIT,
width: 110,
onValue: "search",
offValue: "edit",
checked: mode === 'search',
onChange: setMode,
onBackgroundColor: colors.purple,
offBackgroundColor: colors.green
}), mode === 'edit' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "primary",
disabled: !environment || isBusy,
onClick: () => setModal({
type: 'add',
data: _app_helpers_admin__WEBPACK_IMPORTED_MODULE_5__.DEFAULT_VECTOR
})
}, "Add"))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoToolbar, {
style: {
flex: 'auto'
}
}, mode === 'edit' && /*#__PURE__*/React.createElement(React.Fragment, null, selectedIds.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "primary",
disabled: isBusy,
isBusy: busy === 'bulkPushAll',
onClick: () => onBulkPushClick(false)
}, "Sync Selected"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "danger",
disabled: isBusy,
onClick: deleteSelected
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.DELETE_SELECTED)), selectedIds.length > 0 && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
marginLeft: 10,
marginRight: 10
}
}, selectedIds.length, " selected"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoProgress, {
busy: bulkTasks.busy,
style: {
flex: 'auto'
},
value: bulkTasks.value,
max: bulkTasks.max,
onStopClick: bulkTasks.stop
})), mode === 'search' && /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto',
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoInput, {
style: {
flex: 'auto',
marginRight: 5
},
placeholder: "Search",
disabled: !environment || isBusy,
value: searchInput,
onChange: setSearchInput,
onEnter: onSearchEnter,
onReset: onResetSearch
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "primary",
onClick: onSearchEnter,
disabled: !environment || isBusy || !searchInput,
isBusy: busy === 'searchVectors'
}, "Search"))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoColumn, {
minimal: true,
style: {
flex: 3
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoBlock, {
className: "primary",
title: "Embeddings",
action: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSelect, {
scrolldown: true,
name: "debugMode",
style: {
width: 180
},
disabled: isBusy,
value: debugMode || null,
onChange: setDebugMode
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoOption, {
value: null,
label: "Current Environment"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoOption, {
value: 'includeOrphans',
label: "With Orphans"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoOption, {
value: 'includeAll',
label: "All Envs & Orphans"
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "secondary",
style: {
marginLeft: 5
},
disabled: !environment || busyFetchingVectors,
onClick: () => {
queryClient.invalidateQueries({
queryKey: ['vectors']
});
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.REFRESH)))
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_20__.NekoTable, {
busy: isBusy,
sort: queryParams.sort,
onSortChange: (accessor, by) => {
setQueryParams(prev => ({
...prev,
sort: {
accessor,
by
}
}));
},
emptyMessage: emptyMessage,
data: vectorsRows,
columns: columns,
onSelectRow: id => {
if (selectedIds.length === 1 && selectedIds[0] === id) {
setSelectedIds([]);
}
setSelectedIds([id]);
},
onSelect: ids => {
setSelectedIds([...selectedIds, ...ids]);
},
onUnselect: ids => {
setSelectedIds([...selectedIds.filter(x => !ids.includes(x))]);
},
selectedItems: selectedIds
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), mode !== 'search' && /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoPaging, {
currentPage: queryParams.page,
limit: queryParams.limit,
onCurrentPageChanged: page => setQueryParams(prev => ({
...prev,
page
})),
total: vectorsTotal,
onClick: page => {
setQueryParams(prev => ({
...prev,
page
}));
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "primary",
style: {
marginLeft: 5
},
disabled: !environment,
onClick: () => {
setModal({
type: 'export',
data: {
envId: environmentId
}
});
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].COMMON.EXPORT)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement("div", {
style: {
margin: 8
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 10
}
}, "Settings"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTabs, {
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Environment"
}, /*#__PURE__*/React.createElement("div", {
style: {
padding: '10px 0'
}
}, jsxEnvIndexNS, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
marginRight: 5
}
}, /*#__PURE__*/React.createElement("label", null, "Minimum Score:"), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("span", {
style: {
color: 'var(--neko-green)'
}
}, minScore, "%")), /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
marginLeft: 5
}
}, /*#__PURE__*/React.createElement("label", null, "Max Embedding(s):"), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("span", {
style: {
color: 'var(--neko-green)'
}
}, maxSelect))), /*#__PURE__*/React.createElement("p", null, "The best ", maxSelect, " embedding(s) with a score of ", minScore, " or more will provide additional context."))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Settings"
}, /*#__PURE__*/React.createElement("div", {
style: {
padding: '10px 0'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("label", null, "Min Score (%)"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoInput, {
type: "number",
value: (environment === null || environment === void 0 ? void 0 : environment.min_score) !== undefined ? environment.min_score : 35,
min: 0,
max: 100,
disabled: !environment || isBusy || settingsUpdating,
onFinalChange: async value => {
if (!environment) return;
setSettingsUpdating(true);
try {
const updatedEnvironments = environments.map(env => env.id === environmentId ? {
...env,
min_score: parseInt(value) || 0
} : env);
await updateOption(updatedEnvironments, 'embeddings_envs');
} finally {
setSettingsUpdating(false);
}
}
})), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Max Results"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoInput, {
type: "number",
value: (environment === null || environment === void 0 ? void 0 : environment.max_select) !== undefined ? environment.max_select : 10,
min: 1,
max: 100,
disabled: !environment || isBusy || settingsUpdating,
onFinalChange: async value => {
if (!environment) return;
setSettingsUpdating(true);
try {
const updatedEnvironments = environments.map(env => env.id === environmentId ? {
...env,
max_select: parseInt(value) || 1
} : env);
await updateOption(updatedEnvironments, 'embeddings_envs');
} finally {
setSettingsUpdating(false);
}
}
})))))), mode !== 'search' && /*#__PURE__*/React.createElement("div", {
style: {
margin: "20px 8px 8px 8px"
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 10
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.SYNC_POSTS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTabs, {
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Push",
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, {
line: true
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoSelect, {
id: "postType",
scrolldown: true,
disabled: isBusy,
name: "postType",
style: {
width: 100
},
onChange: setPostType,
value: postType
}, postTypes === null || postTypes === void 0 ? void 0 : postTypes.map(postType => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoOption, {
key: postType.type,
value: postType.type,
label: postType.name
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
className: "primary",
style: {
marginLeft: 10
},
disabled: !environment || isBusy,
isBusy: busy === 'bulkPushAll',
onClick: () => onBulkPushClick(true)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.SYNC_ALL, " ", !isLoadingCount && /*#__PURE__*/React.createElement(React.Fragment, null, "(", `${postsCount}`, ")"))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
className: "primary",
disabled: !environment || isBusy,
isBusy: busy === 'singleRun',
onClick: OnSingleRunClick
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.SYNC_ONE)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Pull",
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
className: "primary",
disabled: !environment || isBusy,
isBusy: busy === 'bulkPullAll',
onClick: () => onBulkPullClick()
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.SYNC_ALL)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Settings",
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_25__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.REWRITE_CONTENT,
disabled: busy,
checked: embeddingsSettings.rewriteContent,
onChange: value => {
setEmbeddingsSettings({
...embeddingsSettings,
rewriteContent: value
});
},
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.REWRITE_CONTENT_DESCRIPTION
}), embeddingsSettings.rewriteContent && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_26__.NekoTextArea, {
value: embeddingsSettings.rewritePrompt,
rows: 5,
disabled: busy,
onBlur: value => {
setEmbeddingsSettings({
...embeddingsSettings,
rewritePrompt: value
});
},
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.REWRITE_PROMPT_DESCRIPTION
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_25__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.FORCE_RECREATE,
checked: embeddingsSettings.forceRecreate,
disabled: busy,
onChange: value => {
setEmbeddingsSettings({
...embeddingsSettings,
forceRecreate: value
});
},
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.FORCE_RECREATE_DESCRIPTION
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
className: "danger",
fullWidth: true,
icon: "trash",
disabled: !environment || busy,
isBusy: busy === 'deleteAllEmbeddings',
onClick: deleteAllEmbeddings
}, busy === 'deleteAllEmbeddings' ? 'Deleting...' : _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.DELETE_ALL_EMBEDDINGS)))), mode !== 'search' && /*#__PURE__*/React.createElement("div", {
style: {
margin: "20px 8px 8px 8px"
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 10
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.AUTO_SYNC_POSTS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTabs, {
inversed: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Status",
inversed: true
}, jsxAutoSyncStatus), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_24__.NekoTab, {
title: "Settings",
inversed: true
}, jsxAutoSyncStatus, environment && isSyncEnvDifferent && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoMessage, {
variant: "danger",
style: {
padding: '10px 20px',
marginBottom: 5
}
}, "The currently selected environment is not used for Auto-Sync. Do you want to use this one?"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
className: "primary",
disabled: isBusy,
onClick: () => setEmbeddingsSettings({
...embeddingsSettings,
syncPostsEnvId: environmentId
}),
style: {
flex: 1
}
}, "Use Current Environment"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, {
tiny: true
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_25__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.AUTO_SYNC_POSTS,
checked: embeddingsSettings.syncPosts,
disabled: busy,
onChange: value => {
setEmbeddingsSettings({
...embeddingsSettings,
syncPosts: value
});
},
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].EMBEDDINGS.AUTO_SYNC_POSTS_DESCRIPTION
}), embeddingsSettings.syncPosts && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoInput, {
name: "syncPostTypes",
value: embeddingsSettings.syncPostTypes,
isCommaSeparatedArray: true,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].HELP.POST_TYPES,
onBlur: value => {
setEmbeddingsSettings({
...embeddingsSettings,
syncPostTypes: value
});
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoInput, {
name: "syncPostStatus",
value: embeddingsSettings.syncPostStatus || "publish",
isCommaSeparatedArray: true,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].HELP.POST_STATUS,
onBlur: value => {
setEmbeddingsSettings({
...embeddingsSettings,
syncPostStatus: value
});
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoInput, {
name: "syncPostCategories",
value: embeddingsSettings.syncPostCategories || "publish",
isCommaSeparatedArray: true,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_9__["default"].HELP.POST_CATEGORIES,
onBlur: value => {
setEmbeddingsSettings({
...embeddingsSettings,
syncPostCategories: value
});
}
}))))), mode !== 'search' && /*#__PURE__*/React.createElement("div", {
style: {
margin: "20px 8px 8px 8px"
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 10
}
}, "Import Data"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoBlock, {
className: "primary",
style: {
margin: "-20px -10px -10px -10px"
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_27__.NekoUploadDropArea, {
ref: ref,
onSelectFiles: onSelectFiles,
accept: ''
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
className: "secondary",
disabled: !environment || isBusy,
onClick: () => ref.current.click()
}, "From CSV or JSON")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoButton, {
fullWidth: true,
className: "secondary",
disabled: !environment || isBusy,
onClick: () => setModal({
type: 'pdf-import'
})
}, "From PDF"))))), /*#__PURE__*/React.createElement(_AddModifyModal__WEBPACK_IMPORTED_MODULE_28__["default"], {
modal: modal,
setModal: setModal,
busy: busy,
onAddEmbedding: onAddEmbedding,
onModifyEmbedding: onModifyEmbedding
}), /*#__PURE__*/React.createElement(_ExportModal__WEBPACK_IMPORTED_MODULE_29__["default"], {
modal: modal,
setModal: setModal,
busy: busy
}), /*#__PURE__*/React.createElement(_ImportModal__WEBPACK_IMPORTED_MODULE_30__["default"], {
modal: modal,
setModal: setModal,
busy: busy,
onAddEmbedding: onAddEmbedding,
onModifyEmbedding: onModifyEmbedding
}), /*#__PURE__*/React.createElement(_pdfImport_modal__WEBPACK_IMPORTED_MODULE_31__["default"], {
modal: modal,
setModal: setModal,
onAddEmbedding: onAddEmbedding,
environment: environment
}), bulkTasks.TasksErrorModal, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_32__.NekoModal, {
isOpen: !!importError,
title: (importError === null || importError === void 0 ? void 0 : importError.title) || "Import Error",
onRequestClose: () => setImportError(null),
okButton: {
label: "Close",
onClick: () => setImportError(null)
},
content: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", {
style: {
marginBottom: 10
}
}, importError === null || importError === void 0 ? void 0 : importError.message), (importError === null || importError === void 0 ? void 0 : importError.details) && /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 10,
borderRadius: 4,
marginBottom: 10,
fontFamily: 'monospace',
fontSize: '12px',
whiteSpace: 'pre-wrap',
maxHeight: '150px',
overflowY: 'auto'
}
}, importError.details), (importError === null || importError === void 0 ? void 0 : importError.help) && /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#e8f4f8',
padding: 10,
borderRadius: 4,
fontSize: '13px',
whiteSpace: 'pre-wrap'
}
}, /*#__PURE__*/React.createElement("strong", null, "Help:"), /*#__PURE__*/React.createElement("br", null), importError.help))
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_32__.NekoModal, {
isOpen: !!syncResults,
title: (syncResults === null || syncResults === void 0 ? void 0 : syncResults.type) === 'push' ? "Sync Complete" : "Pull Complete",
onRequestClose: () => setSyncResults(null),
okButton: {
label: "Close",
onClick: () => setSyncResults(null)
},
content: syncResults && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: syncResults.stats.errors > 0 ? '#fff8e6' : '#e8f5e9',
padding: 15,
borderRadius: 8,
marginBottom: 20,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoTypo, {
h3: true,
style: {
marginBottom: 10,
color: syncResults.stats.errors > 0 ? colors.orange : colors.green
}
}, syncResults.stats.errors > 0 ? '⚠️ Sync Completed with Warnings' : '✅ All Done'), /*#__PURE__*/React.createElement("p", {
style: {
fontSize: '14px',
marginBottom: 0
}
}, syncResults.type === 'push' ? `${syncResults.stats.updated} updated, ${syncResults.stats.added} added, ${syncResults.stats.upToDate} up-to-date` : `Successfully pulled ${syncResults.stats.added} embeddings from the vector database`)), /*#__PURE__*/React.createElement("div", {
style: {
display: 'grid',
gridTemplateColumns: syncResults.type === 'pull' ? '1fr 1fr' : '1fr 1fr 1fr 1fr',
gap: 10,
marginBottom: 20
}
}, syncResults.type === 'push' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 15,
borderRadius: 6,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '24px',
fontWeight: 'bold',
color: colors.green
}
}, syncResults.stats.updated), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '12px',
color: '#666',
marginTop: 5
}
}, "Updated")), /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 15,
borderRadius: 6,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '24px',
fontWeight: 'bold',
color: colors.blue
}
}, syncResults.stats.added), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '12px',
color: '#666',
marginTop: 5
}
}, "Added")), /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 15,
borderRadius: 6,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '24px',
fontWeight: 'bold',
color: colors.lightGray
}
}, syncResults.stats.upToDate), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '12px',
color: '#666',
marginTop: 5
}
}, "Up to Date")), /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 15,
borderRadius: 6,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '24px',
fontWeight: 'bold',
color: syncResults.stats.errors > 0 ? colors.red : colors.lightGray
}
}, syncResults.stats.errors), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '12px',
color: '#666',
marginTop: 5
}
}, "Errors"))) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 15,
borderRadius: 6,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '24px',
fontWeight: 'bold',
color: colors.green
}
}, syncResults.stats.added), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '12px',
color: '#666',
marginTop: 5
}
}, "Pulled")), /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#f5f5f5',
padding: 15,
borderRadius: 6,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '24px',
fontWeight: 'bold',
color: colors.lightGray
}
}, syncResults.stats.alreadySynced), /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '12px',
color: '#666',
marginTop: 5
}
}, "Already Synced")))), syncResults.stats.errors > 0 && /*#__PURE__*/React.createElement("div", {
style: {
backgroundColor: '#ffebee',
padding: 15,
borderRadius: 6,
marginBottom: 15
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
marginBottom: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
icon: "alert",
color: colors.red,
width: 20
}), /*#__PURE__*/React.createElement("span", {
style: {
marginLeft: 8,
fontWeight: 'bold',
color: colors.red
}
}, syncResults.stats.errors, " Error", syncResults.stats.errors > 1 ? 's' : '')), syncResults.stats.errorDetails.length > 0 && /*#__PURE__*/React.createElement("div", {
style: {
maxHeight: '120px',
overflowY: 'auto',
fontSize: '12px',
backgroundColor: '#fff',
padding: 10,
borderRadius: 4,
border: '1px solid #ffcdd2'
}
}, syncResults.stats.errorDetails.slice(0, 5).map((detail, idx) => /*#__PURE__*/React.createElement("div", {
key: idx,
style: {
marginBottom: 5
}
}, /*#__PURE__*/React.createElement("strong", null, detail.postId ? `Post #${detail.postId}` : detail.title || `Item ${idx + 1}`, ":"), " ", detail.error)), syncResults.stats.errorDetails.length > 5 && /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10,
color: '#666'
}
}, "...and ", syncResults.stats.errorDetails.length - 5, " more errors"))), syncResults.type === 'pull' && /*#__PURE__*/React.createElement("div", {
style: {
fontSize: '13px',
color: '#666',
marginTop: 15,
padding: 10,
backgroundColor: '#f9f9f9',
borderRadius: 4
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
icon: "info",
width: 16,
style: {
marginRight: 5,
verticalAlign: 'middle'
}
}), `${syncResults.stats.remoteTotal} total embeddings found in the vector database.`))
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Embeddings);
/***/ }),
/***/ "./app/js/screens/embeddings/Environments.js":
/*!***************************************************!*\
!*** ./app/js/screens/embeddings/Environments.js ***!
\***************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
// React & Vendor Libs
const {
useMemo,
useState
} = wp.element;
const EnvironmentDetails = ({
env,
updateEnvironment,
deleteEnvironment,
ai_envs,
options
}) => {
const {
embeddingsModels
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.useModels)(options, env === null || env === void 0 ? void 0 : env.ai_embeddings_env);
const [testBusy, setTestBusy] = useState(false);
const [testResults, setTestResults] = useState(null);
// Filter AI environments to only show those with embedding models
const ai_envs_with_embeddings = useMemo(() => {
if (!ai_envs || !(options !== null && options !== void 0 && options.ai_engines)) return [];
return ai_envs.filter(aiEnv => {
// Find the engine that matches this environment's type
const engine = options.ai_engines.find(eng => eng.type === aiEnv.type);
if (!engine || !engine.models) return false;
// Check if any models in this engine have the embedding tag
const hasEmbeddingModels = engine.models.some(model => {
var _model$tags;
return model === null || model === void 0 || (_model$tags = model.tags) === null || _model$tags === void 0 ? void 0 : _model$tags.includes('embedding');
});
return hasEmbeddingModels;
});
}, [ai_envs, options]);
const currentEmbeddingsModel = useMemo(() => {
return embeddingsModels.find(x => x.model === env.ai_embeddings_model);
}, [embeddingsModels, env.ai_embeddings_model]);
const currentEmbeddingsModelDimensions = useMemo(() => {
var _currentEmbeddingsMod;
if (!currentEmbeddingsModel) return [];
if (!currentEmbeddingsModel.dimensions) {
console.error('This embeddings model does not have dimensions:', currentEmbeddingsModel);
return [];
}
// Check if the model supports matryoshka (dimension truncation)
const isMatryoshka = currentEmbeddingsModel === null || currentEmbeddingsModel === void 0 || (_currentEmbeddingsMod = currentEmbeddingsModel.tags) === null || _currentEmbeddingsMod === void 0 ? void 0 : _currentEmbeddingsMod.includes('matryoshka');
if (isMatryoshka && currentEmbeddingsModel.dimensions.length > 0) {
const maxDimension = currentEmbeddingsModel.dimensions[0];
// Common matryoshka dimensions in descending order
const matryoshkaDimensions = [3072, 2048, 1536, 1024, 768, 512];
// Filter dimensions that are <= the model's max dimension
return matryoshkaDimensions.filter(dim => dim <= maxDimension);
}
// For non-matryoshka models, return the original dimensions
return currentEmbeddingsModel.dimensions;
}, [currentEmbeddingsModel]);
// Check if selected dimensions match vector DB dimensions
const dimensionMismatch = useMemo(() => {
if (!env.ai_embeddings_dimensions) {
return false;
}
if (env.type === 'pinecone' && env.pinecone_dimensions) {
return parseInt(env.pinecone_dimensions) !== parseInt(env.ai_embeddings_dimensions);
}
if (env.type === 'qdrant' && env.qdrant_dimensions) {
return parseInt(env.qdrant_dimensions) !== parseInt(env.ai_embeddings_dimensions);
}
return false;
}, [env.pinecone_dimensions, env.qdrant_dimensions, env.ai_embeddings_dimensions, env.type]);
const handleQuickTest = async () => {
setTestBusy(true);
try {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/embeddings/test_pinecone`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
json: {
env_id: env.id
}
});
setTestResults(response);
// If test successful and we got dimensions, update the environment
if (response.success && response.dimension) {
updateEnvironment(env.id, {
pinecone_dimensions: response.dimension
});
}
} catch (error) {
setTestResults({
success: false,
error: error.message || 'Failed to test Pinecone connection'
});
} finally {
setTestBusy(false);
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.NAME
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "name",
value: env.name,
onFinalChange: value => updateEnvironment(env.id, {
name: value
})
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.TYPE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoSelect, {
scrolldown: true,
name: "type",
value: env.type,
description: env.type === 'qdrant' ? (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].HELP.QDRANT) : null,
onChange: value => updateEnvironment(env.id, {
type: value
})
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
value: "pinecone",
label: "Pinecone"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
value: "qdrant",
label: "Qdrant"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.API_KEY
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "apikey",
value: env.apikey,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(env.type === 'pinecone' ? _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.PINECONE_APIKEY_HELP : _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.QDRANT_APIKEY_HELP),
onFinalChange: value => updateEnvironment(env.id, {
apikey: value
})
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.SERVER
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "server",
value: env.server,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(env.type === 'qdrant' ? _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.QDRANT_SERVER_HELP : _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.PINECONE_SERVER_HELP),
onFinalChange: value => updateEnvironment(env.id, {
server: value
})
})), env.type === 'pinecone' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.NAMESPACE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "namespace",
value: env.namespace,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.PINECONE_NAMESPACE_HELP),
onFinalChange: value => updateEnvironment(env.id, {
namespace: value
})
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.DIMENSIONS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "pinecone_dimensions",
value: env.pinecone_dimensions || '',
readOnly: true,
placeholder: "Run Quick Test",
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)("The vector dimensions of your Pinecone index. This is detected automatically when you run Quick Test and should match your embedding model's output dimensions.")
}))), env.type === 'qdrant' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.QDRANT_COLLECTION
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "collection",
value: env.collection,
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.QDRANT_COLLECTION_HELP),
onFinalChange: value => updateEnvironment(env.id, {
collection: value
})
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.DIMENSIONS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "qdrant_dimensions",
value: env.qdrant_dimensions || '',
readOnly: true,
placeholder: "Detected from collection",
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)("The vector dimensions of your Qdrant collection. This should match your embedding model's output dimensions.")
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: "Env ID"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "env_id",
value: env.id,
readOnly: true,
description: "The unique identifier for this environment"
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordions, {
keepState: "embeddingsEnvs"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordion, {
title: "Score"
}, /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.MIN_SCORE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "min_score",
value: env.min_score || 35,
type: "number",
min: "0",
max: "100",
step: "1",
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].HELP.MIN_SCORE),
onFinalChange: value => updateEnvironment(env.id, {
min_score: value
})
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.MAX_SELECT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "max_select",
value: env.max_select || 10,
type: "number",
min: "1",
max: "100",
step: "1",
description: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].HELP.MAX_SELECT),
onFinalChange: value => updateEnvironment(env.id, {
max_select: value
})
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordion, {
title: /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: '8px'
}
}, /*#__PURE__*/React.createElement("span", null, _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.AI_ENVIRONMENT), dimensionMismatch && (env === null || env === void 0 ? void 0 : env.ai_embeddings_override) && /*#__PURE__*/React.createElement("small", {
style: {
color: 'var(--neko-red)',
fontWeight: 'bold'
}
}, "(Dimension Mismatch)"))
}, /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.OVERRIDE_DEFAULTS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoCheckbox, {
label: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.ENABLE,
value: "1",
checked: env === null || env === void 0 ? void 0 : env.ai_embeddings_override,
onChange: value => updateEnvironment(env.id, {
ai_embeddings_override: value
})
})), (env === null || env === void 0 ? void 0 : env.ai_embeddings_override) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.ENVIRONMENT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoSelect, {
scrolldown: true,
name: "ai_embeddings_env",
value: env === null || env === void 0 ? void 0 : env.ai_embeddings_env,
onChange: value => updateEnvironment(env.id, {
ai_embeddings_env: value
})
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
key: null,
value: null,
label: "None"
}), ai_envs_with_embeddings.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.MODEL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoSelect, {
scrolldown: true,
name: "ai_embeddings_model",
value: env.ai_embeddings_model,
onChange: value => updateEnvironment(env.id, {
ai_embeddings_model: value
})
}, embeddingsModels.map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
key: x.model,
value: x.model,
label: x.name
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.DIMENSIONS
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoSelect, {
scrolldown: true,
name: "ai_embeddings_dimensions",
value: env.ai_embeddings_dimensions || null,
onChange: value => updateEnvironment(env.id, {
ai_embeddings_dimensions: value
})
}, currentEmbeddingsModelDimensions.map((x, i) => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
key: x,
value: x,
label: i === 0 ? `${x} (Native)` : x
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoOption, {
key: null,
value: null,
label: "Not Set"
}))), dimensionMismatch && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoMessage, {
variant: "warning",
style: {
marginTop: 10,
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Dimension Mismatch:"), " Your ", env.type === 'pinecone' ? 'Pinecone index' : 'Qdrant collection', " has ", env.type === 'pinecone' ? env.pinecone_dimensions : env.qdrant_dimensions, " dimensions, but the selected embedding model is configured for ", env.ai_embeddings_dimensions, " dimensions. This will cause errors when trying to store embeddings. Please select a matching dimension size or use a different embedding model.")))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.ACTIONS
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 10,
justifyContent: 'flex-end'
}
}, env.type === 'pinecone' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
className: "primary",
onClick: handleQuickTest,
isBusy: testBusy
}, "Quick Test"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
className: "danger",
onClick: () => deleteEnvironment(env.id)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_4__["default"].COMMON.DELETE)))), testResults && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoModal, {
title: "Pinecone Connection Test",
isOpen: !!testResults,
onRequestClose: () => setTestResults(null),
okButton: {
label: 'Close',
onClick: () => setTestResults(null)
},
content: /*#__PURE__*/React.createElement("div", null, testResults.success ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoMessage, {
variant: "success",
style: {
marginBottom: 15
}
}, "Connection successful!"), /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Status:"), " ", testResults.ready ? /*#__PURE__*/React.createElement("span", {
style: {
color: 'green'
}
}, "Ready") : /*#__PURE__*/React.createElement("span", {
style: {
color: 'orange'
}
}, "Not Ready")), /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Name:"), " ", testResults.index_name), /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Metric:"), " ", testResults.metric, testResults.metric === 'cosine' ? /*#__PURE__*/React.createElement("span", {
style: {
color: 'green'
}
}, " \u2713") : /*#__PURE__*/React.createElement("span", {
style: {
color: 'orange'
}
}, " (expected: cosine)")), /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Dimensions:"), " ", testResults.dimension, testResults.dimension_match ? /*#__PURE__*/React.createElement("span", {
style: {
color: 'green'
}
}, " \u2713 (matches configuration)") : /*#__PURE__*/React.createElement("span", {
style: {
color: 'red'
}
}, " \u2717 (expected: ", testResults.expected_dimension, ")")), testResults.host && /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Host:"), " ", testResults.host)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoMessage, {
variant: "danger",
style: {
marginBottom: 15
}
}, "Connection failed"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Error:"), " ", testResults.error)))
}));
};
function EmbeddingsEnvironmentsSettings({
environments,
updateEnvironment,
updateOption,
options,
busy
}) {
const addNewEnvironment = () => {
//alert("Coming soon! Please give us a bit of time to beta test this.");
//return;
const newEnv = {
name: 'New Environment',
type: 'pinecone',
apikey: '',
server: '',
indexes: [],
namespaces: []
};
const updatedEnvironments = [...environments, newEnv];
updateOption(updatedEnvironments, 'embeddings_envs');
};
const deleteEnvironment = id => {
if (environments.length === 1) {
alert("You can't delete the last environment.");
return;
}
const updatedEnvironments = environments.filter(env => env.id !== id);
updateOption(updatedEnvironments, 'embeddings_envs');
};
return /*#__PURE__*/React.createElement("div", {
style: {
padding: '0px 10px 20px 10px',
marginTop: 13
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoTypo, {
h2: true,
style: {
color: 'white'
}
}, "Environments for Embeddings"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTabs, {
inversed: true,
style: {
marginTop: -5
},
action: /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoButton, {
rounded: true,
className: "secondary",
icon: "plus",
onClick: addNewEnvironment
})
}, environments.map(env => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
key: env.id,
title: env.name,
busy: busy
}, /*#__PURE__*/React.createElement(EnvironmentDetails, {
env: env,
updateEnvironment: updateEnvironment,
deleteEnvironment: deleteEnvironment,
ai_envs: (options === null || options === void 0 ? void 0 : options.ai_envs) || [],
options: options
})))));
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EmbeddingsEnvironmentsSettings);
/***/ }),
/***/ "./app/js/screens/embeddings/ExportModal.js":
/*!**************************************************!*\
!*** ./app/js/screens/embeddings/ExportModal.js ***!
\**************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! papaparse */ "./node_modules/papaparse/papaparse.min.js");
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(papaparse__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
// React & Vendor Libs
const {
useState
} = wp.element;
// NekoUI
// TODO: This is also present in Finetunes.js (exportAsJSON)
// Maybe we could move this to helpers-admin.js
function downloadAsFile(data, filename) {
const blob = new Blob([data], {
type: 'text/plain;charset=utf-8;'
});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
const ExportModal = ({
modal,
setModal
}) => {
const [busy, setBusy] = useState(false);
const [total, setTotal] = useState(0);
const [count, setCount] = useState(0);
const modalData = modal === null || modal === void 0 ? void 0 : modal.data;
const exportJSON = async () => {
try {
setBusy(true);
const vectors = await retrieveAllVectors();
const json = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoStringify)(vectors, 2);
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
downloadAsFile(json, `vectors-${year}-${month}-${day}.json`);
setTimeout(() => {
setTotal(0);
}, 1000);
} catch (err) {
console.error(err);
alert("An error occurred while exporting vectors. Check your console.");
} finally {
setBusy(false);
}
};
const exportCSV = async () => {
try {
setBusy(true);
const vectors = await retrieveAllVectors();
const csv = papaparse__WEBPACK_IMPORTED_MODULE_0___default().unparse(vectors);
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
downloadAsFile(csv, `vectors-${year}-${month}-${day}.csv`);
setTimeout(() => {
setTotal(0);
}, 1000);
} catch (err) {
console.error(err);
alert("An error occurred while exporting vectors. Check your console.");
} finally {
setBusy(false);
}
};
const retrieveAllVectors = async () => {
let finished = false;
const params = {
page: 1,
limit: 20,
filters: {
envId: modalData.envId,
dbIndex: modalData.dbIndex,
dbNS: modalData.dbNS
}
};
let vectors = [];
while (!finished) {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_2__.retrieveVectors)(params);
if (res.vectors.length < 2) {
finished = true;
}
setTotal(() => res.total);
vectors = vectors.concat(res.vectors);
setCount(() => vectors.length);
params.page++;
}
return vectors;
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoModal, {
isOpen: (modal === null || modal === void 0 ? void 0 : modal.type) === 'export',
title: "Export Embeddings",
onRequestClose: () => setModal(null),
okButton: {
label: "Close",
disabled: busy,
onClick: () => setModal(null)
},
customButtons: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
onClick: exportCSV,
disabled: busy
}, "Export CSV"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
onClick: exportJSON,
disabled: busy
}, "Export JSON")),
content: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoProgress, {
busy: busy,
style: {
flex: 'auto'
},
value: count,
max: total
}))
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ExportModal);
/***/ }),
/***/ "./app/js/screens/embeddings/ImportModal.js":
/*!**************************************************!*\
!*** ./app/js/screens/embeddings/ImportModal.js ***!
\**************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
// React & Vendor Libs
const {
useState
} = wp.element;
// NekoUI
const ImportModal = ({
modal,
setModal,
onAddEmbedding,
onModifyEmbedding
}) => {
var _modal$data;
const [busy, setBusy] = useState(false);
const [total, setTotal] = useState(0);
const [count, setCount] = useState(0);
const [readyVectors, setReadyVectors] = useState({
add: [],
modify: [],
same: [],
total: 0,
isReady: false
});
const importVectors = (modal === null || modal === void 0 || (_modal$data = modal.data) === null || _modal$data === void 0 ? void 0 : _modal$data.importVectors) ?? [];
const [embeddingBasedOn, setEmbeddingBasedOn] = useState({
envId: false,
dbId: false,
dbIndex: false,
dbNS: false,
title: true,
refId: true
});
const modalData = modal === null || modal === void 0 ? void 0 : modal.data;
const createCleanVector = importVector => {
return {
id: importVector.id ?? null,
type: importVector.type ?? 'manual',
title: importVector.title ?? 'N/A',
behavior: importVector.behavior ?? 'context',
envId: (modalData === null || modalData === void 0 ? void 0 : modalData.envId) ?? null,
dbId: importVector.dbId ?? null,
dbIndex: modalData.dbIndex ?? null,
dbNS: modalData.dbNS ?? null,
content: importVector.content ?? '',
refId: importVector.refId ?? null
};
};
const isSameVector = (x, cleanVector, embeddingBasedOn) => {
return Object.keys(embeddingBasedOn).every(key => {
return embeddingBasedOn[key] ? x[key] === cleanVector[key] : true;
});
};
const calculateDiff = async (currentVectors, importVectors) => {
const addVectors = [];
const modifyVectors = [];
const sameVectors = [];
// eslint-disable-next-line no-console
console.log('Calculate Diff', {
currentVectors,
importVectors
});
for (const importVector of importVectors) {
const cleanVector = createCleanVector(importVector);
const matchedVector = currentVectors.find(x => isSameVector(x, cleanVector, embeddingBasedOn));
// eslint-disable-next-line no-console
console.log("Matched Vector", {
cleanVector: {
...cleanVector
},
matchedVector: {
...matchedVector
}
});
if (matchedVector) {
cleanVector.id = matchedVector.id;
} else {
delete cleanVector.id;
}
const sameVector = currentVectors.find(x => x.id === cleanVector.id);
if (sameVector && cleanVector.content === sameVector.content && cleanVector.title === sameVector.title) {
sameVectors.push(cleanVector);
} else if (cleanVector.id) {
modifyVectors.push(cleanVector);
} else {
addVectors.push(cleanVector);
}
}
const total = addVectors.length + modifyVectors.length;
setReadyVectors({
add: addVectors,
modify: modifyVectors,
same: sameVectors,
total,
isReady: true
});
// eslint-disable-next-line no-console
console.log("Embeddings Diff", {
add: addVectors,
modify: modifyVectors,
same: sameVectors,
total
});
};
const runStepOne = async () => {
try {
let finished = false;
const params = {
page: 1,
limit: 20,
filters: {
envId: modalData.envId,
dbIndex: modalData.dbIndex,
dbNS: modalData.dbNS
}
};
let vectors = [];
setBusy('stepOne');
while (!finished) {
const res = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.retrieveVectors)(params);
if (res.vectors.length < 2) {
finished = true;
}
setTotal(() => res.total);
vectors = vectors.concat(res.vectors);
setCount(() => vectors.length);
params.page++;
}
calculateDiff(vectors, importVectors);
} catch (err) {
console.error(err);
alert("An error occurred while retrieving your current embeddings. Check your console.");
} finally {
setBusy(false);
}
};
const runStepTwo = async () => {
try {
setTotal(readyVectors.add.length + readyVectors.modify.length);
setCount(0);
setBusy('stepTwo');
for (const vector of readyVectors.add) {
await onAddEmbedding(vector, true);
setCount(count => count + 1);
}
for (const vector of readyVectors.modify) {
await onModifyEmbedding(vector, true);
setCount(count => count + 1);
}
alert("All embeddings have been updated.");
setReadyVectors({
add: [],
modify: [],
same: [],
total: 0,
isReady: false
});
onClosed();
} catch (err) {
console.error(err);
alert("An error occurred while updating embeddings. Check your console.");
} finally {
setBusy(false);
}
};
const onClosed = () => {
setModal(null);
setBusy(false);
setTotal(0);
setCount(0);
setReadyVectors({
add: [],
modify: [],
same: [],
total: 0,
isReady: false
});
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoModal, {
isOpen: (modal === null || modal === void 0 ? void 0 : modal.type) === 'import',
title: "Import Embeddings",
onRequestClose: onClosed,
okButton: {
label: "Close",
onClick: onClosed,
disabled: busy
},
customButtons: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoButton, {
onClick: runStepOne,
disabled: busy
}, "Check Differences"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoButton, {
onClick: runStepTwo,
disabled: busy || readyVectors.total === 0
}, "Apply Changes")),
content: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "There are ", /*#__PURE__*/React.createElement("b", null, importVectors.length, " embeddings"), " in the file."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoAccordion, {
title: "1 - Check Differences"
}), /*#__PURE__*/React.createElement("p", null, "Calculates the differences between the embeddings in your file and the ones currently registered in AI Engine. Based on that, a list of changes will be created. Please note that the environment, index and namespace that might be set in the file will be ignored."), /*#__PURE__*/React.createElement("p", {
style: {
marginTop: 10
}
}, "An embedding will be considered the same entry based on:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 15
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoCheckbox, {
small: true,
label: "DB ID",
disabled: false,
checked: embeddingBasedOn.dbId,
onChange: () => setEmbeddingBasedOn({
...embeddingBasedOn,
dbId: !embeddingBasedOn.dbId
})
})), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 15
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoCheckbox, {
small: true,
label: "Title",
disabled: false,
checked: embeddingBasedOn.title,
onChange: () => setEmbeddingBasedOn({
...embeddingBasedOn,
title: !embeddingBasedOn.title
})
})), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 15
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoCheckbox, {
small: true,
label: "Ref (Post ID)",
disabled: false,
checked: embeddingBasedOn.refId,
onChange: () => setEmbeddingBasedOn({
...embeddingBasedOn,
refId: !embeddingBasedOn.refId
})
}))), busy === 'stepOne' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoProgress, {
busy: busy,
style: {
flex: 'auto'
},
value: count,
max: total
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoAccordion, {
title: "2 - Apply Changes"
}), !readyVectors.isReady && /*#__PURE__*/React.createElement("i", null, "Waiting for diff..."), readyVectors.isReady && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "There are ", readyVectors.same.length >= 1 && /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("b", null, readyVectors.same.length, " identical embeddings"), " (with the same title and content). They will be ignored.\xA0"), /*#__PURE__*/React.createElement("span", null, "Changes to apply:")), /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, "\uD83D\uDC49 Add: ", /*#__PURE__*/React.createElement("b", null, readyVectors.add.length)), /*#__PURE__*/React.createElement("li", null, "\uD83D\uDC49 Modify: ", /*#__PURE__*/React.createElement("b", null, readyVectors.modify.length)))), busy === 'stepTwo' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoProgress, {
busy: busy,
style: {
flex: 'auto'
},
value: count,
max: total
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoSpacer, null))
}));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ImportModal);
/***/ }),
/***/ "./app/js/screens/embeddings/pdfImport/AnalyzeStep.js":
/*!************************************************************!*\
!*** ./app/js/screens/embeddings/pdfImport/AnalyzeStep.js ***!
\************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
// React & Vendor Libs
const {
useState
} = wp.element;
// NekoUI
// Dynamic PDF.js loader
let pdfjsLib = null;
const loadPDFjs = async () => {
if (!pdfjsLib) {
pdfjsLib = await __webpack_require__.e(/*! import() */ "pdfjs").then(__webpack_require__.bind(__webpack_require__, /*! pdfjs-dist */ "./node_modules/pdfjs-dist/build/pdf.mjs"));
pdfjsLib.GlobalWorkerOptions.workerSrc = `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.pluginUrl}/app/pdf.worker.min.js`;
}
return pdfjsLib;
};
const AnalyzeStep = ({
fileInputRef,
pdfFile,
setPdfFile,
pdfData,
setPdfData,
chunks,
setChunks,
editableChunks,
setEditableChunks,
chunkingDensity,
busy,
setBusy,
error,
setError
}) => {
var _pdfData$detectedHead;
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.useNekoColors)();
const [parseProgress, setParseProgress] = useState(0);
const [currentPage, setCurrentPage] = useState(0);
const [chunkingStage, setChunkingStage] = useState(''); // 'analyzing' or 'titles'
const detectHeadings = textContent => {
const headings = [];
let currentY = null;
let currentLine = [];
const lines = [];
// Group items into lines based on Y position
textContent.items.forEach(item => {
if (currentY === null || Math.abs(item.transform[5] - currentY) > 2) {
if (currentLine.length > 0) {
var _currentLine$, _currentLine$2;
lines.push({
text: currentLine.map(i => i.str).join(' ').trim(),
items: currentLine,
y: currentY,
height: ((_currentLine$ = currentLine[0]) === null || _currentLine$ === void 0 ? void 0 : _currentLine$.height) || 0,
fontName: ((_currentLine$2 = currentLine[0]) === null || _currentLine$2 === void 0 ? void 0 : _currentLine$2.fontName) || ''
});
}
currentLine = [item];
currentY = item.transform[5];
} else {
currentLine.push(item);
}
});
// Add the last line
if (currentLine.length > 0) {
var _currentLine$3, _currentLine$4;
lines.push({
text: currentLine.map(i => i.str).join(' ').trim(),
items: currentLine,
y: currentY,
height: ((_currentLine$3 = currentLine[0]) === null || _currentLine$3 === void 0 ? void 0 : _currentLine$3.height) || 0,
fontName: ((_currentLine$4 = currentLine[0]) === null || _currentLine$4 === void 0 ? void 0 : _currentLine$4.fontName) || ''
});
}
// Analyze lines to find potential headings
const avgHeight = lines.reduce((sum, line) => sum + line.height, 0) / lines.length;
lines.forEach((line, index) => {
const text = line.text;
const isLargerFont = line.height > avgHeight * 1.2;
const isShortLine = text.split(' ').length <= 10;
const isNumbered = /^(Chapter\s+\d+|CHAPTER\s+\d+|\d+\.|Part\s+\d+|Section\s+\d+)/i.test(text);
const isAllCaps = text === text.toUpperCase() && text.length > 3;
const hasColonEnd = text.endsWith(':');
// Check if it's likely a heading
if (text.length > 3 && (isLargerFont && isShortLine || isNumbered || isAllCaps && isShortLine || hasColonEnd && isShortLine)) {
headings.push({
text: text,
pageIndex: 0,
// Will be set later
lineIndex: index,
confidence: (isLargerFont ? 0.3 : 0) + (isNumbered ? 0.4 : 0) + (isAllCaps ? 0.2 : 0) + (hasColonEnd ? 0.1 : 0)
});
}
});
return headings.filter(h => h.confidence >= 0.3);
};
const handleFileSelect = async event => {
const file = event.target.files[0];
if (!file || !file.type.includes('pdf')) {
setError('Please select a valid PDF file');
return;
}
console.log('[PDF Import] File selected:', file.name, 'Size:', file.size);
setPdfFile(file);
setError(null);
setBusy(true);
try {
console.log('[PDF Import] Starting PDF parsing...');
const pdfjsLibrary = await loadPDFjs();
const arrayBuffer = await file.arrayBuffer();
const pdf = await pdfjsLibrary.getDocument({
data: arrayBuffer
}).promise;
console.log('[PDF Import] PDF loaded, pages:', pdf.numPages);
let fullText = '';
const pageTexts = [];
const detectedHeadings = [];
for (let i = 1; i <= pdf.numPages; i++) {
console.log(`[PDF Import] Extracting text from page ${i}/${pdf.numPages}`);
const page = await pdf.getPage(i);
const textContent = await page.getTextContent();
// Detect headings in this page
const pageHeadings = detectHeadings(textContent);
pageHeadings.forEach(heading => {
heading.pageIndex = i - 1;
detectedHeadings.push(heading);
});
const pageText = textContent.items.map(item => item.str).join(' ');
pageTexts.push(pageText);
fullText += pageText + '\n\n';
setCurrentPage(i);
setParseProgress(i / pdf.numPages * 100);
}
const wordCount = fullText.split(/\s+/).filter(w => w.length > 0).length;
console.log('[PDF Import] Text extraction complete. Words:', wordCount, 'Characters:', fullText.length);
console.log('[PDF Import] Detected headings:', detectedHeadings.length);
const pdfInfo = {
numPages: pdf.numPages,
wordCount,
fullText,
pageTexts,
fileName: file.name,
detectedHeadings: detectedHeadings.length >= 3 ? detectedHeadings : []
};
setPdfData(pdfInfo);
// Always generate chunks with default token-based method
await generateChunks(fullText, pageTexts, chunkingDensity, pdfInfo);
} catch (err) {
console.error('[PDF Import] PDF parsing error:', err);
setError('Failed to parse PDF: ' + err.message);
} finally {
setBusy(false);
}
};
const generateChunks = async (fullText, pageTexts, density, pdfInfo) => {
setBusy(true);
setError(null);
setChunkingStage('analyzing');
console.log('[PDF Import] Starting chunking with density:', density);
if (density === 5 && fullText.length > 10000) {
const estimatedChunks = Math.ceil(fullText.length / 1000);
console.log('[PDF Import] Very high density warning - estimated chunks:', estimatedChunks);
if (estimatedChunks > 50) {
setError(`Note: Very High density may create ${estimatedChunks}+ small chunks. This might take a moment...`);
}
}
try {
const controller = new AbortController();
// Dynamic timeout based on text size and density
const baseTimeout = 30000; // 30 seconds base
const sizeMultiplier = Math.ceil(fullText.length / 50000); // +30s per 50k chars
const densityMultiplier = density >= 4 ? 2 : 1; // Double timeout for high/very high density
const timeout = baseTimeout * sizeMultiplier * densityMultiplier;
console.log('[PDF Import] Sending chunking request to server...');
console.log('[PDF Import] Timeout set to:', timeout / 1000, 'seconds (size multiplier:', sizeMultiplier, ', density multiplier:', densityMultiplier, ')');
// Set stage to titles generation after initial processing
setTimeout(() => {
if (busy) {
setChunkingStage('titles');
}
}, 3000); // Switch to titles stage after 3 seconds
const timeoutId = setTimeout(() => controller.abort(), timeout);
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl}/vectors/chunk`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce,
method: 'POST',
json: {
text: fullText,
pageTexts,
density,
fileName: (pdfInfo === null || pdfInfo === void 0 ? void 0 : pdfInfo.fileName) || 'document.pdf'
},
signal: controller.signal
});
clearTimeout(timeoutId);
if (response.chunks) {
console.log('[PDF Import] Received chunks:', response.chunks.length);
setChunks(response.chunks);
setEditableChunks(response.chunks.map((chunk, idx) => ({
...chunk,
id: `chunk_${idx}`,
enabled: true
})));
setError(null);
}
} catch (err) {
console.error('[PDF Import] Chunking error:', err);
if (err.name === 'AbortError') {
const estimatedTime = Math.ceil(baseTimeout * Math.ceil(fullText.length / 50000) * (density >= 4 ? 2 : 1) / 1000);
setError(`Processing is taking longer than expected (>${estimatedTime}s). This might be due to the PDF size or selected density. Try a lower density setting or split the PDF into smaller sections.`);
} else {
setError('Failed to generate chunks: ' + err.message);
}
} finally {
setBusy(false);
setChunkingStage('');
}
};
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
flex: 1
}
}, /*#__PURE__*/React.createElement("input", {
ref: fileInputRef,
type: "file",
accept: ".pdf",
onChange: handleFileSelect,
style: {
display: 'none'
},
disabled: busy
}), /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoBlock, {
className: "primary",
style: {
maxWidth: 400
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: 20
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
h3: true,
style: {
marginBottom: 10
}
}, "Upload PDF Document"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
p: true,
style: {
color: colors.grey,
textAlign: 'center',
marginBottom: 10
}
}, "Select a PDF file to extract its content and create embeddings"), !pdfData && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "primary",
onClick: () => {
var _fileInputRef$current;
return (_fileInputRef$current = fileInputRef.current) === null || _fileInputRef$current === void 0 ? void 0 : _fileInputRef$current.click();
},
disabled: busy,
isBusy: busy,
style: {
height: 50,
fontSize: 16,
minWidth: 250
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoIcon, {
icon: "upload",
style: {
marginRight: 8
}
}), "Select PDF"), busy && /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 20,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
small: true,
style: {
color: colors.grey
}
}, !pdfData ? 'Parsing PDF pages...' : chunkingStage === 'titles' ? 'Generating descriptive titles...' : 'Creating sections...'), chunkingDensity >= 4 && pdfData && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
small: true,
style: {
color: colors.orange,
marginTop: 10
}
}, "High density setting may take longer")), pdfData && !busy && chunks.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
background: colors.lightGrey,
padding: 20,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
borderRadius: 8,
marginTop: 20,
marginBottom: 20,
width: '100%'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoIcon, {
icon: "check-circle",
width: 24,
color: colors.green,
style: {
marginBottom: 10
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
h4: true,
style: {
margin: 0
}
}, pdfData.fileName), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
small: true,
style: {
color: colors.grey,
textAlign: 'center',
margin: '4px 0'
}
}, pdfData.numPages, " pages \u2022 ", pdfData.wordCount.toLocaleString(), " words"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
small: true,
style: {
color: colors.grey,
margin: 0
}
}, chunks.length, " sections created"), ((_pdfData$detectedHead = pdfData.detectedHeadings) === null || _pdfData$detectedHead === void 0 ? void 0 : _pdfData$detectedHead.length) > 0 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
small: true,
style: {
color: colors.primary,
marginTop: 4
}
}, pdfData.detectedHeadings.length, " chapters detected")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "primary",
onClick: () => window.dispatchEvent(new CustomEvent('pdf-import-continue')),
style: {
height: 50,
fontSize: 16,
minWidth: 200
}
}, "Continue"))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AnalyzeStep);
/***/ }),
/***/ "./app/js/screens/embeddings/pdfImport/ChunkItem.js":
/*!**********************************************************!*\
!*** ./app/js/screens/embeddings/pdfImport/ChunkItem.js ***!
\**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _app_styles_AiIcon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/styles/AiIcon */ "./app/js/styles/AiIcon.js");
// React & Vendor Libs
const {} = wp.element;
// NekoUI
const ChunkItem = ({
chunk,
viewMode,
onToggle,
onUpdateTitle,
onGenerateTitle,
busy,
colors
}) => {
return /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'flex-start',
gap: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_0__.NekoCheckbox, {
checked: chunk.enabled,
onChange: () => onToggle(chunk.id)
}), /*#__PURE__*/React.createElement("div", {
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: 8
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoInput, {
value: chunk.title,
onChange: value => onUpdateTitle(chunk.id, value),
style: {
flex: 1
},
disabled: !chunk.enabled,
placeholder: "Enter section title..."
}), chunk.enabled && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoButton, {
size: "small",
className: "secondary",
onClick: () => onGenerateTitle(chunk),
disabled: busy,
title: "Generate AI title",
style: {
padding: '6px 10px'
}
}, /*#__PURE__*/React.createElement(_app_styles_AiIcon__WEBPACK_IMPORTED_MODULE_3__["default"], {
icon: "wand",
style: {
width: 16,
height: 16
}
}))), chunk.enabled && /*#__PURE__*/React.createElement("div", {
style: {
fontSize: 12,
color: colors.grey,
marginTop: 2,
display: 'flex',
gap: 5
}
}, /*#__PURE__*/React.createElement("span", null, chunk.pageRange), /*#__PURE__*/React.createElement("span", null, "\u2022"), /*#__PURE__*/React.createElement("span", null, chunk.tokens, " tokens")), viewMode === 'detailed' && /*#__PURE__*/React.createElement("div", {
style: {
color: colors.darkGrey,
marginTop: 8,
marginBottom: 8,
maxHeight: 80,
overflow: 'hidden',
lineHeight: 1.5,
position: 'relative'
}
}, chunk.content.substring(0, 200), chunk.content.length > 200 && /*#__PURE__*/React.createElement("span", {
style: {
position: 'absolute',
bottom: 0,
right: 0,
background: `linear-gradient(to right, transparent, ${colors.lightGrey})`,
padding: '0 10px'
}
}, "...")))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChunkItem);
/***/ }),
/***/ "./app/js/screens/embeddings/pdfImport/DensityControl.js":
/*!***************************************************************!*\
!*** ./app/js/screens/embeddings/pdfImport/DensityControl.js ***!
\***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
// React & Vendor Libs
const {} = wp.element;
// NekoUI
const DensityControl = ({
density,
onDensityChange,
busy
}) => {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_0__.NekoBlock, {
className: "primary",
title: "Chunking Density"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSelect, {
value: density,
onChange: onDensityChange,
disabled: busy,
isBusy: busy,
style: {
width: '100%'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoOption, {
value: 1,
label: "Very Low (~3000 tokens)"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoOption, {
value: 2,
label: "Low (~2000 tokens)"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoOption, {
value: 3,
label: "Medium (~1000 tokens)"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoOption, {
value: 4,
label: "High (~500 tokens)"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoOption, {
value: 5,
label: "Very High (~250 tokens)"
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (DensityControl);
/***/ }),
/***/ "./app/js/screens/embeddings/pdfImport/IntegrateStep.js":
/*!**************************************************************!*\
!*** ./app/js/screens/embeddings/pdfImport/IntegrateStep.js ***!
\**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
// React & Vendor Libs
const {
useEffect
} = wp.element;
// NekoUI
const IntegrateStep = ({
editableChunks,
uploadProgress,
setUploadProgress,
uploadedCount,
setUploadedCount,
onAddEmbedding,
environment,
busy,
setBusy,
error,
setError,
onComplete
}) => {
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.useNekoColors)();
const enabledChunks = editableChunks.filter(c => c.enabled);
const handleUpload = async () => {
if (enabledChunks.length === 0) {
setError('Please select at least one chunk to upload');
return;
}
setBusy(true);
setUploadedCount(0);
setError(null);
try {
for (let i = 0; i < enabledChunks.length; i++) {
const chunk = enabledChunks[i];
await onAddEmbedding({
type: 'manual',
title: chunk.title,
content: chunk.content,
envId: environment === null || environment === void 0 ? void 0 : environment.id,
behavior: 'context'
}, true);
setUploadedCount(i + 1);
setUploadProgress((i + 1) / enabledChunks.length * 100);
}
onComplete();
} catch (err) {
console.error('Upload error:', err);
setError('Failed to upload embeddings: ' + err.message);
} finally {
setBusy(false);
}
};
useEffect(() => {
const handleUploadEvent = () => handleUpload();
window.addEventListener('pdf-import-upload', handleUploadEvent);
return () => window.removeEventListener('pdf-import-upload', handleUploadEvent);
}, [enabledChunks]);
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
flex: 1
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoBlock, {
className: "primary",
style: {
maxWidth: 500
}
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: 20
}
}, uploadProgress === 0 && !busy && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
icon: "database",
width: 48,
color: colors.blue,
style: {
marginBottom: 20
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
h3: true,
style: {
marginBottom: 10
}
}, "Ready to Create Embeddings"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
p: true,
style: {
color: colors.grey,
textAlign: 'center'
}
}, enabledChunks.length, " sections will be processed and added to your knowledge base")), uploadProgress > 0 && uploadProgress < 100 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
h3: true,
style: {
marginBottom: 20
}
}, "Creating Embeddings..."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoProgress, {
value: uploadProgress,
max: 100,
style: {
marginBottom: 10
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
small: true,
style: {
color: colors.grey
}
}, "Processing section ", uploadedCount, " of ", enabledChunks.length)), uploadProgress === 100 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
icon: "check-circle",
width: 48,
color: colors.green,
style: {
marginBottom: 20
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
h3: true,
style: {
marginBottom: 10
}
}, "All Done!"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
p: true,
style: {
color: colors.grey,
textAlign: 'center'
}
}, "Successfully created ", enabledChunks.length, " embeddings"))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (IntegrateStep);
/***/ }),
/***/ "./app/js/screens/embeddings/pdfImport/OptimizeStep.js":
/*!*************************************************************!*\
!*** ./app/js/screens/embeddings/pdfImport/OptimizeStep.js ***!
\*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _ChunkItem__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ChunkItem */ "./app/js/screens/embeddings/pdfImport/ChunkItem.js");
/* harmony import */ var _DensityControl__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./DensityControl */ "./app/js/screens/embeddings/pdfImport/DensityControl.js");
/* harmony import */ var _app_styles_AiIcon__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @app/styles/AiIcon */ "./app/js/styles/AiIcon.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
// React & Vendor Libs
const {
useState,
useMemo
} = wp.element;
// NekoUI
// Components
const OptimizeStep = ({
editableChunks,
setEditableChunks,
chunks,
setChunks,
chunkingDensity,
setChunkingDensity,
pdfData,
busy,
setBusy,
setError
}) => {
var _pdfData$detectedHead, _pdfData$detectedHead2;
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.useNekoColors)();
const [viewMode, setViewMode] = useState('compact');
const [chunkingType, setChunkingType] = useState('tokens');
const enabledCount = useMemo(() => editableChunks.filter(c => c.enabled).length, [editableChunks]);
const toggleChunk = chunkId => {
setEditableChunks(prev => prev.map(chunk => chunk.id === chunkId ? {
...chunk,
enabled: !chunk.enabled
} : chunk));
};
const updateChunkTitle = (chunkId, newTitle) => {
setEditableChunks(prev => prev.map(chunk => chunk.id === chunkId ? {
...chunk,
title: newTitle
} : chunk));
};
const handleDensityChange = async newDensity => {
setChunkingDensity(newDensity);
if (pdfData) {
await regenerateChunks(newDensity, chunkingType);
}
};
const handleChunkingTypeChange = async newType => {
setChunkingType(newType);
if (pdfData) {
await regenerateChunks(chunkingDensity, newType);
}
};
const regenerateChunks = async (density, type = 'tokens') => {
setBusy(true);
setError(null);
try {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/vectors/chunk`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
method: 'POST',
json: {
text: pdfData.fullText,
pageTexts: pdfData.pageTexts,
density,
fileName: pdfData.fileName,
chunkingType: type,
detectedHeadings: type === 'chapters' ? pdfData.detectedHeadings : []
}
});
if (response.chunks) {
setChunks(response.chunks);
setEditableChunks(response.chunks.map((chunk, idx) => ({
...chunk,
id: `chunk_${idx}`,
enabled: true
})));
}
} catch (err) {
setError('Failed to regenerate chunks: ' + err.message);
} finally {
setBusy(false);
}
};
const generateSingleTitle = async chunk => {
setBusy(true);
setError(null);
try {
const contentPreview = chunk.content.substring(0, 1000).trim();
const prompt = `Read this text section and create a clear, descriptive title (max 50 characters) that captures its main topic. Reply with ONLY the title, nothing else:\n\n${contentPreview}`;
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/simpleTextQuery`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
method: 'POST',
json: {
message: prompt,
options: {
scope: 'embeddings-title',
max_tokens: 25,
temperature: 0.2
}
}
});
if (response.success && response.data) {
const title = response.data.trim().replace(/^["']|["']$/g, '');
if (title && title.length > 5 && title.length <= 100) {
updateChunkTitle(chunk.id, title);
}
} else {
setError(response.message || 'Failed to generate title');
}
} catch (err) {
setError(err.message || 'Failed to generate title');
} finally {
setBusy(false);
}
};
const generateAllTitles = async () => {
setBusy(true);
setError(null);
try {
const enabledChunks = editableChunks.filter(c => c.enabled);
const batchSize = 5;
for (let i = 0; i < enabledChunks.length; i += batchSize) {
const batch = enabledChunks.slice(i, i + batchSize);
const promises = batch.map(async chunk => {
try {
const contentPreview = chunk.content.substring(0, 1000).trim();
const prompt = `Read this text section and create a clear, descriptive title (max 50 characters) that captures its main topic. Reply with ONLY the title, nothing else:\n\n${contentPreview}`;
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_2__.apiUrl}/simpleTextQuery`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_2__.restNonce,
method: 'POST',
json: {
message: prompt,
options: {
scope: 'embeddings-title',
max_tokens: 25,
temperature: 0.2
}
}
});
if (response.success && response.data) {
const title = response.data.trim().replace(/^["']|["']$/g, '');
if (title && title.length > 5 && title.length <= 100) {
return {
chunkId: chunk.id,
title
};
}
}
} catch (err) {
console.error('Failed to generate title for chunk:', err);
}
return null;
});
const results = await Promise.all(promises);
setEditableChunks(prev => {
const updated = [...prev];
results.forEach(result => {
if (result && result.title) {
const idx = updated.findIndex(c => c.id === result.chunkId);
if (idx >= 0) {
updated[idx].title = result.title;
}
}
});
return updated;
});
}
} catch (err) {
setError('Failed to generate titles with AI');
} finally {
setBusy(false);
}
};
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'row',
flex: 1
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoColumn, {
minimal: true,
style: {
flex: 3,
display: 'flex',
backgroundColor: 'var(--neko-main-color)'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
className: "primary",
title: `Sections (${enabledCount}/${editableChunks.length})`,
style: {
flex: 1,
display: 'flex',
flexDirection: 'column'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
minHeight: 0,
overflowY: 'auto',
overflowX: 'hidden'
}
}, editableChunks.map(chunk => /*#__PURE__*/React.createElement(_ChunkItem__WEBPACK_IMPORTED_MODULE_5__["default"], {
key: chunk.id,
chunk: chunk,
viewMode: viewMode,
onToggle: toggleChunk,
onUpdateTitle: updateChunkTitle,
onGenerateTitle: generateSingleTitle,
busy: busy,
colors: colors
}))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoColumn, {
minimal: true,
style: {
flex: 1,
marginLeft: 10,
backgroundColor: 'var(--neko-main-color)'
}
}, (!(pdfData !== null && pdfData !== void 0 && (_pdfData$detectedHead = pdfData.detectedHeadings) !== null && _pdfData$detectedHead !== void 0 && _pdfData$detectedHead.length) || chunkingType === 'tokens') && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_DensityControl__WEBPACK_IMPORTED_MODULE_6__["default"], {
density: chunkingDensity,
onDensityChange: handleDensityChange,
busy: busy
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
})), (pdfData === null || pdfData === void 0 || (_pdfData$detectedHead2 = pdfData.detectedHeadings) === null || _pdfData$detectedHead2 === void 0 ? void 0 : _pdfData$detectedHead2.length) > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
className: "primary",
title: "Chunking Type"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
value: chunkingType,
onChange: handleChunkingTypeChange,
disabled: busy,
style: {
width: '100%'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "tokens",
label: "By Tokens - Split based on token count"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "chapters",
label: `By Chapters - Use ${pdfData.detectedHeadings.length} detected chapters`
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
className: "primary",
title: "AI Title Generation"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoButton, {
fullWidth: true,
className: "secondary",
onClick: generateAllTitles,
disabled: enabledCount === 0,
isBusy: busy,
style: {
height: 50,
fontSize: 16
}
}, /*#__PURE__*/React.createElement(_app_styles_AiIcon__WEBPACK_IMPORTED_MODULE_10__["default"], {
icon: "wand",
style: {
marginRight: 8,
width: 16,
height: 16
}
}), "Auto-Generate All Titles")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
className: "primary",
title: "View Mode"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
value: viewMode,
onChange: setViewMode,
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "compact",
label: "Compact"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "detailed",
label: "Detailed"
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
className: "primary",
title: "Information"
}, /*#__PURE__*/React.createElement("p", null, "Each section will become a separate embedding in your knowledge base."))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (OptimizeStep);
/***/ }),
/***/ "./app/js/screens/embeddings/pdfImport/modal.js":
/*!******************************************************!*\
!*** ./app/js/screens/embeddings/pdfImport/modal.js ***!
\******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _AnalyzeStep__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AnalyzeStep */ "./app/js/screens/embeddings/pdfImport/AnalyzeStep.js");
/* harmony import */ var _OptimizeStep__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OptimizeStep */ "./app/js/screens/embeddings/pdfImport/OptimizeStep.js");
/* harmony import */ var _IntegrateStep__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./IntegrateStep */ "./app/js/screens/embeddings/pdfImport/IntegrateStep.js");
// React & Vendor Libs
const {
useState,
useRef,
useEffect
} = wp.element;
// NekoUI
// Components
// PDF.js will be loaded dynamically when needed
const PDFImportModal = ({
modal,
setModal,
onAddEmbedding,
environment
}) => {
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.useNekoColors)();
const [step, setStep] = useState('analyze');
const [pdfFile, setPdfFile] = useState(null);
const [pdfData, setPdfData] = useState(null);
const [chunks, setChunks] = useState([]);
const [editableChunks, setEditableChunks] = useState([]);
const [chunkingDensity, setChunkingDensity] = useState(3);
const [uploadProgress, setUploadProgress] = useState(0);
const [uploadedCount, setUploadedCount] = useState(0);
const [busy, setBusy] = useState(false);
const [error, setError] = useState(null);
const fileInputRef = useRef(null);
const reset = () => {
setStep('analyze');
setPdfFile(null);
setPdfData(null);
setChunks([]);
setEditableChunks([]);
setUploadProgress(0);
setUploadedCount(0);
setBusy(false);
setError(null);
};
const canProceed = () => {
switch (step) {
case 'analyze':
return pdfData !== null && !busy;
case 'optimize':
return editableChunks.some(c => c.enabled) && !busy;
case 'integrate':
return false;
default:
return false;
}
};
const handleNext = () => {
if (step === 'analyze') {
setStep('optimize');
} else if (step === 'optimize') {
setStep('integrate');
}
};
const handleBack = () => {
if (step === 'optimize') {
setStep('analyze');
} else if (step === 'integrate') {
setStep('optimize');
}
};
// Listen for continue event from AnalyzeStep
useEffect(() => {
const handleContinue = () => {
if (step === 'analyze' && pdfData !== null && !busy) {
setStep('optimize');
}
};
window.addEventListener('pdf-import-continue', handleContinue);
return () => window.removeEventListener('pdf-import-continue', handleContinue);
}, [step, pdfData, busy]);
const getStepContent = () => {
switch (step) {
case 'analyze':
return /*#__PURE__*/React.createElement(_AnalyzeStep__WEBPACK_IMPORTED_MODULE_1__["default"], {
fileInputRef: fileInputRef,
pdfFile: pdfFile,
setPdfFile: setPdfFile,
pdfData: pdfData,
setPdfData: setPdfData,
chunks: chunks,
setChunks: setChunks,
editableChunks: editableChunks,
setEditableChunks: setEditableChunks,
chunkingDensity: chunkingDensity,
busy: busy,
setBusy: setBusy,
error: error,
setError: setError
});
case 'optimize':
return /*#__PURE__*/React.createElement(_OptimizeStep__WEBPACK_IMPORTED_MODULE_2__["default"], {
editableChunks: editableChunks,
setEditableChunks: setEditableChunks,
chunks: chunks,
setChunks: setChunks,
chunkingDensity: chunkingDensity,
setChunkingDensity: setChunkingDensity,
pdfData: pdfData,
busy: busy,
setBusy: setBusy,
error: error,
setError: setError
});
case 'integrate':
return /*#__PURE__*/React.createElement(_IntegrateStep__WEBPACK_IMPORTED_MODULE_3__["default"], {
editableChunks: editableChunks,
uploadProgress: uploadProgress,
setUploadProgress: setUploadProgress,
uploadedCount: uploadedCount,
setUploadedCount: setUploadedCount,
onAddEmbedding: onAddEmbedding,
environment: environment,
busy: busy,
setBusy: setBusy,
error: error,
setError: setError,
onComplete: () => {
setTimeout(() => {
setModal(null);
reset();
}, 1000);
}
});
}
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoModal, {
title: "Import from PDF",
size: "full-size",
style: {
backgroundColor: 'var(--neko-main-color)'
},
isOpen: (modal === null || modal === void 0 ? void 0 : modal.type) === 'pdf-import',
onRequestClose: () => {
setModal(null);
reset();
},
customButtons: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
onClick: () => {
setModal(null);
reset();
},
disabled: busy
}, "Close"), step !== 'analyze' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
onClick: handleBack,
disabled: busy
}, "Back"), step !== 'integrate' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "primary",
onClick: handleNext,
disabled: !canProceed()
}, "Continue"), step === 'integrate' && uploadProgress !== 100 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "primary",
onClick: () => {
const enabledChunks = editableChunks.filter(c => c.enabled);
if (enabledChunks.length === 0) {
setError('Please select at least one chunk to upload');
return;
}
// Trigger upload in IntegrateStep
window.dispatchEvent(new CustomEvent('pdf-import-upload'));
},
disabled: busy
}, "Upload Embeddings")),
content: /*#__PURE__*/React.createElement(React.Fragment, null, error && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoMessage, {
variant: "danger"
}, error), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null)), /*#__PURE__*/React.createElement("div", {
style: {
flex: 1,
minHeight: 0,
display: 'flex',
flexDirection: 'column'
}
}, getStepContent())),
contentStyle: {
margin: '0 -15px',
padding: '10px 15px',
height: '100%',
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
backgroundColor: 'var(--neko-main-color)'
}
});
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PDFImportModal);
/***/ }),
/***/ "./app/js/screens/finetunes/Finetunes.js":
/*!***********************************************!*\
!*** ./app/js/screens/finetunes/Finetunes.js ***!
\***********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! papaparse */ "./node_modules/papaparse/papaparse.min.js");
/* harmony import */ var papaparse__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(papaparse__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Icon.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/table/Table.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/toolbar/Toolbar.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Switch.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/UploadDropArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Paging.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Container.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _app_screens_finetunes_Generator__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! @app/screens/finetunes/Generator */ "./app/js/screens/finetunes/Generator.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
// React & Vendor Libs
const {
useState,
useMemo,
useRef,
useEffect
} = wp.element;
// NekoUI
const EstimationMessage = ({
createdOn,
estimatedOn
}) => {
if (!createdOn || !estimatedOn) return null;
const now = new Date();
createdOn = new Date(createdOn);
estimatedOn = new Date(estimatedOn);
const formatDate = date => {
return new Date(date).toLocaleString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
};
const calculateTimeDifference = (start, end) => {
const diff = end - start;
const minutes = Math.floor(diff / (1000 * 60));
const hours = Math.floor(minutes / 60);
if (hours > 0) {
return `${hours} hour${hours > 1 ? 's' : ''} and ${minutes % 60} minute${minutes % 60 !== 1 ? 's' : ''}`;
}
return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
};
return /*#__PURE__*/React.createElement("div", null, "Start: ", formatDate(createdOn), ".", /*#__PURE__*/React.createElement("br", null), "Finish: ", formatDate(estimatedOn), ".", /*#__PURE__*/React.createElement("br", null), "Time Left: ", /*#__PURE__*/React.createElement("b", null, calculateTimeDifference(now, estimatedOn)), ".", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, "Use Refresh Models to update the status."));
};
const builderColumnsEasy = [{
accessor: 'row',
title: "#",
width: '25px',
verticalAlign: 'top'
}, {
accessor: 'question',
title: 'Question',
width: '50%',
verticalAlign: 'top'
}, {
accessor: 'answer',
title: 'Answer',
width: '50%',
verticalAlign: 'top'
}, {
accessor: 'actions',
title: '',
width: '36px',
align: 'center'
}];
const builderColumnsExpert = [{
accessor: 'row',
title: "#",
width: '25px',
verticalAlign: 'top'
}, {
accessor: 'messages',
title: 'Messages',
width: '100%',
verticalAlign: 'top'
}, {
accessor: 'actions',
title: '',
width: '68px',
align: 'top'
}];
const fileColumns = [{
accessor: 'status',
title: 'Status',
sortable: true,
width: '120px'
}, {
accessor: 'id',
title: 'ID',
width: '120px'
}, {
accessor: 'filename',
title: 'File',
width: '50%'
}, {
accessor: 'purpose',
title: 'Purpose',
width: '50%'
}, {
accessor: 'filesize',
title: 'Size',
width: '80px',
sortable: true
}, {
accessor: 'createdOn',
title: 'Date',
sortable: true,
width: '120px'
}, {
accessor: 'actions',
title: '',
width: '200px'
}];
const fineTuneColumns = [{
accessor: 'status',
title: 'Status',
sortable: true,
width: '120px'
}, {
accessor: 'id',
title: 'ID',
width: '120px'
}, {
accessor: 'suffix',
title: 'Suffix',
width: '20%'
}, {
accessor: 'model',
title: 'Model',
width: '40%'
}, {
accessor: 'base_model',
title: 'Based On',
width: '40%'
}, {
accessor: 'createdOn',
title: 'Date',
sortable: true,
width: '120px'
}, {
accessor: 'actions',
title: '',
width: '40px'
}];
// Status can be: pending, succeeded, failed, or cancelled
const StatusIcon = ({
status,
includeText = false
}) => {
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.useNekoColors)();
const orange = colors.orange;
const green = colors.green;
const red = colors.red;
// Let's set the right icon and color based on the status
let icon = null;
switch (status) {
case 'pending':
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "replay",
spinning: true,
width: 24,
color: orange
});
break;
case 'running':
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "replay",
spinning: true,
width: 24,
color: orange
});
break;
case 'succeeded':
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "check-circle",
width: 24,
color: green
});
break;
case 'processed':
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "check-circle",
width: 24,
color: green
});
break;
case 'failed':
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "close",
width: 24,
color: red
});
break;
case 'cancelled':
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "close",
width: 24,
color: orange
});
break;
default:
icon = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoIcon, {
title: status,
icon: "alert",
width: 24,
color: orange
});
break;
}
if (includeText) {
return /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center'
}
}, icon, /*#__PURE__*/React.createElement("span", {
style: {
textTransform: 'uppercase',
fontSize: 9,
marginLeft: 3
}
}, status));
}
return icon;
};
const EditableText = ({
children,
data,
onChange = () => {}
}) => {
const [isEdit, setIsEdit] = useState(false);
const onSave = value => {
setIsEdit(false);
if (value !== data) {
onChange(value);
}
};
const onKeyPress = e => {
if (e.key === 'Escape') {
onSave(data);
}
};
if (isEdit) {
return /*#__PURE__*/React.createElement("div", {
onKeyUp: onKeyPress,
style: {
height: '100%',
display: 'flex',
flexDirection: 'column',
width: '100%'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTextArea, {
onBlurForce: true,
autoFocus: true,
fullHeight: true,
rows: 3,
style: {
height: '100%',
width: '100%'
},
onEnter: onSave,
onBlur: onSave,
value: data
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
onClick: onSave,
fullWidth: true,
style: {
marginTop: 2,
height: 35
}
}, "Save"));
}
return /*#__PURE__*/React.createElement("pre", {
style: {
width: '100%',
height: '100%',
whiteSpace: 'break-spaces',
margin: 0,
padding: 0,
fontSize: 13,
fontFamily: 'inherit'
},
onClick: () => setIsEdit(true)
}, children);
};
const Finetunes = ({
options,
updateOption,
refreshOptions
}) => {
var _options$ai_envs;
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.useNekoColors)();
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.useQueryClient)();
const [errorModal, setErrorModal] = useState(false);
const [fileForFineTune, setFileForFineTune] = useState();
const [busyAction, setBusyAction] = useState(false);
const [section, setSection] = useState('finetunes');
const [modelFilter, setModelFilter] = useState('current');
const [purposeFilter, setPurposeFilter] = useState('fine-tune');
const [suffix, setSuffix] = useState('meow');
const [hyperParams, setHyperParams] = useState(false);
const [nEpochs, setNEpochs] = useState(4);
const [batchSize, setBatchSize] = useState(4);
const [learningRateMultiplier, setLearningRateMultiplier] = useState(0.1);
const [promptLossWeight, setPromptLossWeight] = useState(0.01);
const [datasetsQueryEnabled, setDatasetsQueryEnabled] = useState(false);
const [envId, setEnvId] = useState(options === null || options === void 0 || (_options$ai_envs = options.ai_envs) === null || _options$ai_envs === void 0 || (_options$ai_envs = _options$ai_envs[0]) === null || _options$ai_envs === void 0 ? void 0 : _options$ai_envs.id);
const environments = useMemo(() => (options === null || options === void 0 ? void 0 : options.ai_envs) || [], [options]);
const environment = useMemo(() => environments === null || environments === void 0 ? void 0 : environments.find(x => x.id === envId), [envId, environments]);
const deletedFineTunes = (environment === null || environment === void 0 ? void 0 : environment.finetunes_deleted) || [];
const allFineTunes = (environment === null || environment === void 0 ? void 0 : environment.finetunes) || [];
const {
isFetching: isBusyFiles,
error: errFiles,
data: dataFiles
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__.useQuery)({
queryKey: ['datasets-' + envId + '-' + purposeFilter],
enabled: datasetsQueryEnabled,
queryFn: () => (0,_app_requests__WEBPACK_IMPORTED_MODULE_7__.retrieveFilesFromOpenAI)(envId, purposeFilter)
});
//const { models, model, setModel, getModel, isFineTunedModel } = useModels(options, envId);
const [model, setModel] = useState('gpt-4o-mini-2024-07-18');
const updateEnv = async (option, value) => {
const newEnvs = environments.map(x => {
if (x.id === envId) {
return {
...x,
[option]: value
};
}
return x;
});
return updateOption(newEnvs, 'ai_envs');
};
// const finetunableModels = useMemo(() => {
// return models.filter(x => x.tags?.includes('finetune'));
// }, [models]);
useEffect(() => {
if (section === 'files' && !datasetsQueryEnabled) {
setDatasetsQueryEnabled(true);
}
}, [section]);
// Display errors from useQuery to the error modal
useEffect(() => {
errFiles && !errorModal && setErrorModal(errFiles);
}, [errFiles]);
// For the builder
const rowsPerPage = 10;
const [hasStorageBackup, setHasStorageBackup] = useState(true);
const [currentPage, setCurrentPage] = useState(1);
const [entries, setEntries] = useState([]);
const [isExpert, setIsExpert] = useState(false);
const [instructions, setInstructions] = useState('You are Chihiro, an AI Assistant. Your primary objective is to assist website visitors by directing them to the appropriate page or succinctly answering their questions with precision.');
const [filename, setFilename] = useState('');
const [isValid, setIsValid] = useState(false);
const [invalidEntries, setInvalidEntries] = useState([]);
const totalRows = useMemo(() => entries.length, [entries]);
// For the entries to be valid, we should have:
// - More than 0 entries.
// - Each entry should have at least one message with the role of 'system', then another message with the role of 'user', and finally a message with the role of 'assistant'.
// - There can be more messages but it should always alternate between user and assistant.
useEffect(() => {
if (entries.length === 0) {
setIsValid(false);
return;
}
const invalidIndices = entries.map((x, index) => {
if (!x.messages || x.messages.length < 3) {
return index + 1;
}
if (x.messages[0].role !== 'system' || x.messages[1].role !== 'user' || x.messages[2].role !== 'assistant') {
return index + 1;
}
for (let i = 3; i < x.messages.length; i++) {
if (x.messages[i].role === x.messages[i - 1].role) {
return index + 1;
}
}
return null;
}).filter(index => index !== null);
setInvalidEntries(invalidIndices);
setIsValid(invalidIndices.length === 0);
}, [entries]);
const onDeleteRow = line => {
const newData = entries.filter((x, i) => i !== line - 1);
setEntries(newData);
if (newData.length === 0) {
updateLocalStorage({
instructions,
entries: []
});
}
};
const EditableMessages = ({
messages,
currentRow,
onUpdateDataRow,
onDeleteDataRow
}) => {
return /*#__PURE__*/React.createElement(React.Fragment, null, messages.map((x, messageRow) => /*#__PURE__*/React.createElement("div", {
key: messageRow,
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
rounded: true,
icon: "trash",
onClick: () => onDeleteDataRow(currentRow, messageRow + 1)
}), /*#__PURE__*/React.createElement("div", {
style: {
width: 120,
paddingLeft: 5,
paddingTop: 0,
paddingBottom: 4,
marginRight: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
name: "role",
value: x.role,
style: {
width: 120
},
onChange: value => onUpdateDataRow(currentRow, value, x.content, messageRow + 1)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "assistant",
label: "Assistant"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "user",
label: "User"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
value: "system",
label: "System"
}))), /*#__PURE__*/React.createElement(EditableText, {
data: x.content,
style: {
flex: 'auto'
},
onChange: value => onUpdateDataRow(currentRow, x.role, value, messageRow + 1)
}, x.content))));
};
const refreshFiles = async () => {
await queryClient.invalidateQueries('datasets');
};
const onRefreshFiles = async () => {
setBusyAction(true);
await refreshFiles();
setBusyAction(false);
};
const onStartFineTune = async () => {
const currentFile = fileForFineTune;
const currentSuffix = suffix;
//const rawModel = getModel(model);
setBusyAction(true);
//const isFineTuned = isFineTunedModel(model);
// hyperParams
let json = {
envId: envId,
fileId: currentFile,
model: model,
suffix: currentSuffix
};
if (hyperParams) {
json = {
...json,
nEpochs,
batchSize,
learningRateMultiplier,
promptLossWeight
};
}
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_10__.apiUrl}/openai/files/finetune`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_10__.restNonce,
json: json
});
if (res.success) {
onRefreshFineTunes();
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.FINETUNING_STARTED);
setSection('finetunes');
setFileForFineTune();
} else {
alert(res.message);
}
} catch (err) {
console.log(err.message);
alert(err.message);
}
setBusyAction(false);
};
const onRefreshFineTunes = async () => {
setBusyAction('finetunes');
if (!allFineTunes.length) {
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_7__.retrieveDeletedFineTunes)(envId);
} else {
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_7__.retrieveFineTunes)(envId);
//await retrieveModels();
}
await refreshOptions();
setBusyAction(false);
};
const onCleanFineTunes = async () => {
setBusyAction('clean');
await (0,_app_requests__WEBPACK_IMPORTED_MODULE_7__.retrieveDeletedFineTunes)(envId);
await refreshOptions();
setBusyAction(false);
};
const resetFilename = () => {
const now = new Date();
let prefix = now.toLocaleDateString('ja-JP', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
prefix = prefix.replace(/\//g, '.');
prefix += '-' + now.getHours().toString().padStart(2, '0') + '.' + now.getMinutes().toString().padStart(2, '0');
setFilename(`MEOW-${prefix}.jsonl`);
};
const onClearDataset = (askForConfirmation = true) => {
if (askForConfirmation && !confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.RESET_BUILDER)) {
return;
}
setEntries([]);
updateLocalStorage({
instructions: instructions,
entries: []
});
};
// Load the builder data from local storage
useEffect(() => {
if (!entries || entries.length === 0) {
const data = localStorage.getItem('mwai_builder_data_v2');
if (data) {
const freshData = JSON.parse(data);
setEntries(freshData.entries);
if (freshData.instructions) {
setInstructions(freshData.instructions);
}
}
}
}, []);
const rewriteInstructions = value => {
let shouldReplace = false;
let shouldAdd = false;
for (let i = 0; i < entries.length; i++) {
const currentEntry = entries[i];
const messages = currentEntry.messages;
if (messages && messages.length > 0) {
if (messages[0].role === 'system') {
if (messages[0].content !== value) {
if (!shouldReplace) {
if (confirm("The instructions in your data do not match the ones in your entries. Do you want to replace it for every entry?")) {
shouldReplace = true;
} else {
return;
}
}
const newData = [...entries];
newData[i].messages[0].content = value;
setEntries(() => newData);
}
} else {
if (!shouldAdd) {
if (confirm("Some entries are missing the system role as the first message. Do you want to add it for every entry where it's missing?")) {
shouldAdd = true;
} else {
return;
}
}
const newData = [...entries];
newData[i].messages.unshift({
role: 'system',
content: value
});
setEntries(() => newData);
}
} else {
if (!shouldAdd) {
if (confirm("Some entries are missing the system role as the first message. Do you want to add it for every entry where it's missing?")) {
shouldAdd = true;
} else {
return;
}
}
const newData = [...entries];
newData[i].messages = [{
role: 'system',
content: value
}, ...messages];
setEntries(() => newData);
}
}
};
const updateInstructions = value => {
setInstructions(value);
if (!isExpert) {
rewriteInstructions(value);
}
};
const updateLocalStorage = data => {
resetFilename();
try {
if (!data) {
localStorage.removeItem('mwai_builder_data_v2');
} else {
localStorage.setItem('mwai_builder_data_v2', (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoStringify)(data));
}
setHasStorageBackup(true);
} catch (err) {
localStorage.removeItem('mwai_builder_data_v2');
setHasStorageBackup(false);
}
};
// Save the messages to local storage
useEffect(() => {
if (entries && (entries === null || entries === void 0 ? void 0 : entries.length) > 0) {
updateLocalStorage({
instructions: instructions,
entries
});
}
}, [entries]);
// Save the instructions to local storage
useEffect(() => {
if (instructions && (instructions === null || instructions === void 0 ? void 0 : instructions.length) > 0) {
updateLocalStorage({
instructions: instructions,
entries
});
}
}, [instructions]);
const onDeleteDataRow = (row, messageRow) => {
const updatedEntries = [...entries];
updatedEntries[row - 1].messages.splice(messageRow - 1, 1);
setEntries(updatedEntries);
};
const onUpdateDataRow = (row, role, content, messageRow = null) => {
const newData = entries.map((x, i) => {
if (i === row - 1) {
if (messageRow) {
return {
...x,
messages: x.messages.map((y, j) => {
if (j === messageRow - 1) {
return {
...y,
role,
content
};
}
return y;
})
};
} else if (role === 'assistant') {
return {
...x,
messages: x.messages.map(y => {
if (y.role === 'assistant') {
return {
...y,
content
};
}
return y;
})
};
} else if (role === 'user') {
return {
...x,
messages: x.messages.map(y => {
if (y.role === 'user') {
return {
...y,
content
};
}
return y;
})
};
}
}
return x;
});
setEntries(newData);
};
const builderRows = useMemo(() => {
let row = (currentPage - 1) * rowsPerPage;
const chunkOfBuilderData = entries === null || entries === void 0 ? void 0 : entries.slice((currentPage - 1) * rowsPerPage, (currentPage - 1) * rowsPerPage + rowsPerPage);
return chunkOfBuilderData === null || chunkOfBuilderData === void 0 ? void 0 : chunkOfBuilderData.map(x => {
const currentRow = ++row;
let question = "";
let answer = "";
let messages = [];
if (!isExpert) {
const potentialQuestion = x.messages.find(x => x.role === 'user');
if (potentialQuestion) {
question = potentialQuestion.content;
}
const potentialAnswer = x.messages.find(x => x.role === 'assistant');
if (potentialAnswer) {
answer = potentialAnswer.content;
}
} else {
messages = x.messages;
}
return {
row: currentRow,
messages: /*#__PURE__*/React.createElement(EditableMessages, {
entries: entries,
messages: messages,
currentRow: currentRow,
onUpdateDataRow: onUpdateDataRow,
onDeleteDataRow: onDeleteDataRow
}),
question: /*#__PURE__*/React.createElement(EditableText, {
data: question,
onChange: value => onUpdateDataRow(currentRow, 'user', value)
}, question),
answer: /*#__PURE__*/React.createElement(EditableText, {
data: answer,
onChange: value => onUpdateDataRow(currentRow, 'assistant', value)
}, answer),
actions: /*#__PURE__*/React.createElement(React.Fragment, null, isExpert && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
rounded: true,
icon: "plus",
onClick: () => addMessage(currentRow)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
rounded: true,
icon: "trash",
onClick: () => onDeleteRow(currentRow)
}))
};
});
}, [entries, currentPage, rowsPerPage, isExpert, onUpdateDataRow, onDeleteDataRow]);
const deleteFile = async fileId => {
setBusyAction(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_10__.apiUrl}/openai/files/delete`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_10__.restNonce,
json: {
envId: envId,
fileId
}
});
if (res.success) {
await refreshFiles();
} else {
alert(res.message);
}
} catch (err) {
console.error(err);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.CHECK_CONSOLE);
}
setBusyAction(false);
};
const cancelFineTune = async finetuneId => {
// Are you sure
// if (!confirm(i18n.ALERTS.DELETE_FINETUNE)) {
// return;
// }
setBusyAction(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_10__.apiUrl}/openai/finetunes/cancel`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_10__.restNonce,
json: {
envId: envId,
finetuneId
}
});
if (res.success) {
onRefreshFineTunes();
} else {
alert(res.message);
}
} catch (err) {
console.error(err);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.CHECK_CONSOLE);
}
setBusyAction(false);
};
// Add this finetune job to the deleted list.
// We only want to do this for cancelled and failed jobs.
const removeFineTune = async modelId => {
// Are you sure
if (!confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.DELETE_FINETUNE)) {
return;
}
setBusyAction(true);
try {
await updateEnv('finetunes_deleted', [...deletedFineTunes, modelId]);
} catch (err) {
console.error(err);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.CHECK_CONSOLE);
}
setBusyAction(false);
};
const deleteFineTune = async modelId => {
// Are you sure
if (!confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.DELETE_FINETUNE)) {
return;
}
setBusyAction(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_10__.apiUrl}/openai/finetunes/delete`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_10__.restNonce,
json: {
envId: envId,
modelId
}
});
if (res.success) {
await updateEnv('finetunes_deleted', [...deletedFineTunes, modelId]);
} else {
// If message contains "does not exist"
if (res.message.indexOf('does not exist') > -1) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.FINETUNE_ALREADY_DELETED);
await updateEnv('finetunes_deleted', [...deletedFineTunes, modelId]);
} else {
alert(res.message);
}
}
} catch (err) {
console.error(err);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.CHECK_CONSOLE);
}
setBusyAction(false);
};
const downloadFile = async (fileId, filename) => {
setBusyAction(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_10__.apiUrl}/openai/files/download`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_10__.restNonce,
json: {
envId: envId,
fileId
}
});
if (res.success) {
const blob = new Blob([res.data], {
type: 'text/plain'
});
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', `${filename}`);
document.body.appendChild(link);
link.click();
link.remove();
} else {
alert(res.message);
}
} catch (err) {
console.error(err);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.CHECK_CONSOLE);
}
setBusyAction(false);
};
const fileRows = useMemo(() => {
// Sort the dataFiles by created_at
return dataFiles === null || dataFiles === void 0 ? void 0 : dataFiles.sort((a, b) => b.created_at - a.created_at).map(x => {
const currentId = x.id;
const currentFilename = x.filename;
const createdOn = new Date(x.created_at * 1000);
const forFineTune = x.purpose === 'fine-tune';
return {
status: /*#__PURE__*/React.createElement(StatusIcon, {
status: x.status,
includeText: true
}),
id: currentId,
filename: currentFilename,
purpose: x.purpose,
filesize: (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.formatBytes)(x.bytes),
createdOn: /*#__PURE__*/React.createElement(React.Fragment, null, createdOn.toLocaleDateString(), /*#__PURE__*/React.createElement("br", null), createdOn.toLocaleTimeString()),
actions: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
disabled: !forFineTune,
icon: "wand",
onClick: () => setFileForFineTune(currentId)
}, "Train Model"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
rounded: true,
icon: "arrow-down",
onClick: () => downloadFile(currentId, currentFilename)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "danger",
rounded: true,
icon: "trash",
onClick: () => deleteFile(currentId)
}))
};
});
}, [dataFiles]);
const isDeleted = x => {
return deletedFineTunes.includes(x.model) || deletedFineTunes.includes(x.id);
};
const isFailed = x => {
return x.status === 'failed' || x.status === 'cancelled';
};
const isCurrent = x => {
return !isFailed(x) && !isDeleted(x);
};
const fineTuneRows = useMemo(() => {
if (!allFineTunes) {
return [];
}
let filteredFineTunes = allFineTunes;
if (modelFilter === 'current') {
filteredFineTunes = filteredFineTunes.filter(isCurrent);
} else if (modelFilter === 'deleted') {
filteredFineTunes = filteredFineTunes.filter(isDeleted);
} else if (modelFilter === 'failed') {
filteredFineTunes = filteredFineTunes.filter(isFailed);
}
return filteredFineTunes.map(x => {
const createdOn = new Date(x.createdOn);
return {
...x,
model: x.model ? x.model : /*#__PURE__*/React.createElement(EstimationMessage, {
createdOn: x.createdOn,
estimatedOn: x.estimatedOn
}),
status: /*#__PURE__*/React.createElement(StatusIcon, {
status: x.status,
includeText: true
}),
createdOn: /*#__PURE__*/React.createElement(React.Fragment, null, createdOn.toLocaleDateString(), /*#__PURE__*/React.createElement("br", null), createdOn.toLocaleTimeString()),
actions: /*#__PURE__*/React.createElement(React.Fragment, null, x.status === 'succeeded' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "danger",
rounded: true,
icon: "trash",
onClick: () => deleteFineTune(x.model)
}), x.status === 'cancelled' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "danger",
rounded: true,
icon: "trash",
onClick: () => removeFineTune(x.id)
}), x.status === 'failed' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "danger",
rounded: true,
icon: "trash",
onClick: () => removeFineTune(x.id)
}), x.status === 'pending' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "danger",
rounded: true,
icon: "close",
onClick: () => cancelFineTune(x.id)
}))
};
});
}, [modelFilter, deletedFineTunes, allFineTunes]);
const busy = isBusyFiles || busyAction;
const exportAsJSON = () => {
const json = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoStringify)(entries, 2);
const blob = new Blob([json], {
type: 'text/plain'
});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
const date = new Date();
// Create a filename based on the current date with the time
const filename = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}-WP.json`;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
const onUploadDataSet = async () => {
setBusyAction(true);
try {
const data = entries.map(x => {
const json = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoStringify)(x);
return json;
}).join("\n");
//console.log(data);
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_10__.apiUrl}/openai/files/upload`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_10__.restNonce,
json: {
envId: envId,
filename,
data
}
});
await refreshFiles();
if (res.success) {
onClearDataset(false);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.DATASET_UPLOADED);
setSection('files');
} else {
alert(res.message);
}
} catch (err) {
console.error(err);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.CHECK_CONSOLE);
}
setBusyAction(false);
};
const modelNamePreview = useMemo(() => {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1; // getMonth returns a 0-based value
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
const rawModel = model;
return `${rawModel}:ft-your-org:${suffix}-${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}-${hours < 10 ? '0' + hours : hours}-${minutes < 10 ? '0' + minutes : minutes}-${seconds < 10 ? '0' + seconds : seconds}`;
}, [suffix, model]);
const onSelectFiles = async files => {
// For each file, open with FileReader
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader = new FileReader();
const isJson = file.name.endsWith('.json');
const isJsonl = file.name.endsWith('.jsonl');
const isCsv = file.name.endsWith('.csv');
let isMigration = false;
if (!isJson && !isJsonl && !isCsv) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.ONLY_SUPPORTS_FILES);
console.warn(file);
continue;
}
reader.onload = async e => {
const fileContent = e.target.result;
let data = [];
if (isJson) {
try {
data = JSON.parse(fileContent);
} catch (e) {
console.error(e);
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.ONLY_SUPPORTS_FILES);
return;
}
} else if (isJsonl) {
const lines = fileContent.split('\n');
data = lines.map(x => {
x = x.trim();
try {
return JSON.parse(x);
} catch (e) {
console.error(e, x);
return null;
}
});
const hasMessages = data.every(x => x.messages);
if (!hasMessages) {
isMigration = true;
}
} else if (isCsv) {
const resParse = papaparse__WEBPACK_IMPORTED_MODULE_0___default().parse(fileContent, {
header: true,
skipEmptyLines: true
});
data = resParse.data;
// eslint-disable-next-line no-console
console.log('The CSV was loaded!', data);
isMigration = true;
}
if (isMigration) {
data = data.map(x => {
const values = Object.keys(x).reduce((acc, key) => {
acc[key.toLowerCase()] = x[key];
return acc;
}, {});
isMigration = true;
const promptColumns = ['prompt', 'question', 'q'];
const completionColumns = ['completion', 'reply', 'a'];
const promptKey = promptColumns.find(x => values[x]);
const completionKey = completionColumns.find(x => values[x]);
const promptValue = values[promptKey];
const completionValue = values[completionKey];
const completionValueClean = completionValue === null || completionValue === void 0 ? void 0 : completionValue.replace(/\n\n$/g, '');
const promptValueClean = promptValue === null || promptValue === void 0 ? void 0 : promptValue.replace(/\n\n###\n\n$/g, '');
if (!promptValue || !completionValue) {
return null;
}
return {
messages: [{
role: 'system',
content: instructions
}, {
role: 'user',
content: promptValueClean.trim()
}, {
role: 'assistant',
content: completionValueClean.trim()
}]
};
});
}
// Clean the data
data = data.filter(x => x);
// Check that all the entry in data have a messages array
const hasMessages = data.every(x => x === null || x === void 0 ? void 0 : x.messages);
if (!hasMessages) {
alert(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].ALERTS.ONLY_SUPPORTS_FILES);
return;
}
setEntries(data);
};
reader.readAsText(file);
}
};
const addRow = (question = 'Question?', answer = 'Answer.') => {
setEntries([...entries, {
messages: [{
role: 'system',
content: instructions
}, {
role: 'user',
content: question
}, {
role: 'assistant',
content: answer
}]
}]);
};
const addMessage = (line, role = 'user', content = 'Hello!') => {
const newData = entries.map((x, i) => {
if (i === line - 1) {
return {
...x,
messages: [...x.messages, {
role,
content
}]
};
}
return x;
});
setEntries(newData);
};
const handleInvalidEntryClick = index => {
const page = Math.floor(index / rowsPerPage);
setCurrentPage(page + 1);
};
const ref = useRef(null);
const currentModelsCount = allFineTunes === null || allFineTunes === void 0 ? void 0 : allFineTunes.filter(isCurrent).length;
const failedModelsCount = allFineTunes === null || allFineTunes === void 0 ? void 0 : allFineTunes.filter(isFailed).length;
const deletedModelsCount = allFineTunes === null || allFineTunes === void 0 ? void 0 : allFineTunes.filter(isDeleted).length;
const jsxEnvironments = useMemo(() => {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSelect, {
scrolldown: true,
value: envId,
onChange: setEnvId,
style: {
marginLeft: 5
}
}, environments.filter(x => x.type === 'openai').map(x => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoOption, {
key: x.id,
value: x.id,
label: x.name
})));
}, [envId, environments]);
const jsxInvalidEntries = useMemo(() => {
if (invalidEntries.length === 0) {
return null;
}
const entriesToShow = invalidEntries.slice(0, 10).map((index, idx) => /*#__PURE__*/React.createElement("span", {
key: index,
style: {
cursor: 'pointer',
textDecoration: 'underline'
},
onClick: () => handleInvalidEntryClick(index)
}, index, idx < invalidEntries.slice(0, 10).length - 1 ? ', ' : ''));
if (invalidEntries.length > 10) {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Some entries are invalid, for example those ones: ", entriesToShow, ", and ", invalidEntries.length - 10, " more.");
} else {
return /*#__PURE__*/React.createElement(React.Fragment, null, "Some entries are invalid, for example those ones: ", entriesToShow);
}
}, [invalidEntries, rowsPerPage]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoColumn, {
fullWidth: true,
minimal: true,
style: {
margin: 8
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTabs, {
inversed: true,
currentTab: section,
onChange: (_index, attributes) => {
setSection(attributes.key);
},
action: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), section === 'finetunes' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
disabled: busyAction,
busy: busyAction === 'finetunes',
onClick: onRefreshFineTunes,
className: "secondary"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.REFRESH_MODELS), jsxEnvironments), section === 'files' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
disabled: busyAction,
onClick: onRefreshFiles,
className: "secondary"
}, "Refresh Files"), jsxEnvironments), section === 'editor' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", {
style: {
marginRight: 10
}
}, "Filename:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
disabled: !totalRows || busyAction,
value: totalRows ? filename : '',
onChange: setFilename,
style: {
width: 220,
marginRight: 5
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "secondary",
disabled: !isValid || busyAction,
icon: "upload",
onClick: onUploadDataSet
}, "Upload to OpenAI"), jsxEnvironments))
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.MODELS,
key: "finetunes"
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}
}, /*#__PURE__*/React.createElement("div", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.MODELS_INTRO)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoQuickLinks, {
value: modelFilter,
onChange: value => {
setModelFilter(value);
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoLink, {
title: "Current",
value: "current",
count: currentModelsCount ?? '-'
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoLink, {
title: "Failed",
value: "failed",
count: failedModelsCount ?? '-'
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoLink, {
title: "Deleted",
value: "deleted",
count: deletedModelsCount ?? '-'
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTable, {
busy: busy,
data: fineTuneRows,
columns: fineTuneColumns,
emptyMessage: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.NO_FINETUNES_YET
}), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5,
display: 'flex',
justifyContent: 'end',
lineHeight: '12px',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
small: true,
disabled: busyAction,
busy: busyAction === 'clean',
onClick: onCleanFineTunes,
className: "primary"
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.CLEAN_MODELS_LIST), /*#__PURE__*/React.createElement("small", {
style: {
marginLeft: 5
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.DELETED_FINETUNE_ISSUE))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.FILES,
key: "files"
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}
}, /*#__PURE__*/React.createElement("div", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_9__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.FILES_INTRO)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoQuickLinks, {
value: purposeFilter,
onChange: value => {
setPurposeFilter(value);
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoLink, {
title: "Datasets",
value: "fine-tune"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoLink, {
title: "All",
value: null
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTable, {
busy: busy,
data: fileRows,
columns: fileColumns,
emptyMessage: /*#__PURE__*/React.createElement(React.Fragment, null, "You do not have any dataset files yet.")
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.DATASET_EDITOR,
key: "editor"
}, !hasStorageBackup && /*#__PURE__*/React.createElement("p", {
style: {
color: 'red'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].FINETUNING.HUGE_DATASET_WARNING), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoToolbar, {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
icon: "plus",
onClick: () => addRow(),
disabled: busyAction
}, "Add Entry"), isExpert && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
onClick: () => rewriteInstructions(instructions),
disabled: busyAction
}, "Rewrite Instructions"), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoSwitch, {
style: {
marginLeft: 5
},
onLabel: "Expert",
offLabel: "Easy",
width: 90,
onBackgroundColor: colors.purple,
offBackgroundColor: colors.green,
onChange: setIsExpert,
checked: isExpert
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_20__.NekoUploadDropArea, {
ref: ref,
onSelectFiles: onSelectFiles,
accept: '',
style: {
paddingLeft: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
className: "secondary",
onClick: () => ref.current.click()
}, "Import")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
disabled: !totalRows,
onClick: onClearDataset,
className: "secondary"
}, "Clear")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null), entries.length > 0 && (invalidEntries === null || invalidEntries === void 0 ? void 0 : invalidEntries.length) > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoMessage, {
variant: "danger"
}, jsxInvalidEntries), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoAccordions, {
keepState: "datasetEditor"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoAccordion, {
title: "Dataset"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoPaging, {
currentPage: currentPage,
limit: rowsPerPage,
total: totalRows,
onCurrentPageChanged: setCurrentPage,
onClick: setCurrentPage
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoTable, {
busy: busyAction,
data: builderRows,
columns: isExpert ? builderColumnsExpert : builderColumnsEasy,
emptyMessage: /*#__PURE__*/React.createElement(React.Fragment, null, "You can import a file, or create manually each entry by clicking ", /*#__PURE__*/React.createElement("b", null, "Add"), ".")
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex'
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_23__.NekoPaging, {
currentPage: currentPage,
limit: rowsPerPage,
total: totalRows,
onCurrentPageChanged: setCurrentPage,
onClick: setCurrentPage
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoButton, {
disabled: !totalRows,
style: {
marginLeft: 5
},
onClick: exportAsJSON
}, "Export as JSON"))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_11__["default"].COMMON.CONTEXT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null), /*#__PURE__*/React.createElement("span", null, "The instructions are the same for all entries. It is used as the ", /*#__PURE__*/React.createElement("i", null, "system"), " (and first) message in each conversation. More information ", /*#__PURE__*/React.createElement("a", {
href: "https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset",
target: "_blank",
rel: "noreferrer"
}, "here"), "."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTextArea, {
id: "instructions",
name: "instructions",
rows: 2,
value: instructions,
onBlur: updateInstructions,
onEnter: updateInstructions
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoAccordion, {
title: "Generator"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, null), /*#__PURE__*/React.createElement(_app_screens_finetunes_Generator__WEBPACK_IMPORTED_MODULE_24__["default"], {
options: options,
instructions: instructions,
setMessages: setEntries
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_21__.NekoMessage, {
variant: "danger"
}, "Use this feature with caution. The AI will generate questions and answers for each of your post based on the given prompt, and they will be added to your dataset. Keep in mind that this process may be ", /*#__PURE__*/React.createElement("u", null, "extremely slow"), " and require a ", /*#__PURE__*/React.createElement("u", null, "significant number of API calls"), ", resulting in a ", /*#__PURE__*/React.createElement("u", null, "high cost"), ".")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_22__.NekoAccordion, {
title: "Instructions"
}, /*#__PURE__*/React.createElement("p", null, "You can create your dataset by importing a file (two columns, in the CSV, JSON or JSONL format) or manually by clicking ", /*#__PURE__*/React.createElement("b", null, "Add Entry"), ". For the format, check this ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://gist.github.com/jordymeow/a855df4a1f644bb3df8c78ea87c1a2ca"
}, "JSON Example"), " (more complex) or this ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://gist.github.com/jordymeow/e0c80ebeefe4d4d07ae39995c561ba4a"
}, "CSV Example"), " (simpler). ", /*#__PURE__*/React.createElement("b", null, "Writing datasets is actually complex."), " Please have a look at OpenAI's ", /*#__PURE__*/React.createElement("a", {
href: "https://platform.openai.com/docs/guides/fine-tuning/conditional-generation",
target: "_blank",
rel: "noreferrer"
}, "tutorials"), ". And here is Meow Apps' ", /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com/wordpress-chatbot-finetuned-model-ai/",
target: "_blank",
rel: "noreferrer"
}, "simplified tutorial"), ". Is your dataset ready? Modify the filename to your liking and click ", /*#__PURE__*/React.createElement("b", null, "Upload to OpenAI"), "."), /*#__PURE__*/React.createElement("p", null, "To avoid losing your work, this data is kept in your browser's local storage."))))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_25__.NekoContainer, {
style: {
margin: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_26__.NekoModal, {
isOpen: errorModal,
title: "Error",
onRequestClose: () => setErrorModal(),
okButton: {
label: 'Ok',
onClick: () => setErrorModal()
},
content: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, errorModal === null || errorModal === void 0 ? void 0 : errorModal.message))
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_26__.NekoModal, {
isOpen: fileForFineTune,
title: "Train a new model",
onRequestClose: () => setFileForFineTune(),
okButton: {
label: 'Start',
disabled: busyAction,
onClick: onStartFineTune
},
cancelButton: {
label: 'Close',
disabled: busyAction,
onClick: () => setFileForFineTune()
},
content: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "Exciting! \uD83C\uDFB5 You are about to create your own new model, based on your dataset. You simply need to select a base model, and optionally, to modify the ", /*#__PURE__*/React.createElement("a", {
href: "https://beta.openai.com/docs/guides/fine-tuning/hyperparameters",
target: "_blank",
rel: "noreferrer"
}, "hyperparameters"), ". Before starting the process, make sure that:"), /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, "\u2705 The dataset is well-defined."), /*#__PURE__*/React.createElement("li", null, "\u2705 You understand ", /*#__PURE__*/React.createElement("a", {
href: "https://openai.com/api/pricing/#faq-fine-tuning-pricing-calculation",
target: "_blank",
rel: "noreferrer"
}, "OpenAI pricing"), " about fine-tuning.")), /*#__PURE__*/React.createElement("label", null, "Base model:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
value: model,
onChange: setModel,
description: /*#__PURE__*/React.createElement(React.Fragment, null, "As of August 2024, you can use ", /*#__PURE__*/React.createElement("a", {
href: "#",
onClick: () => setModel('gpt-4o-mini-2024-07-18')
}, "gpt-4o-mini-2024-07-18"), ", ", /*#__PURE__*/React.createElement("a", {
href: "#",
onClick: () => setModel('gpt-3.5-turbo-0125')
}, "gpt-3.5-turbo-0125"), ", or any of your previously fine-tuned models. Check all the available models ", /*#__PURE__*/React.createElement("a", {
href: "https://platform.openai.com/docs/guides/fine-tuning/which-models-can-be-fine-tuned",
target: "_blank",
rel: "noreferrer"
}, "here"), ".")
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
height: 10
}), /*#__PURE__*/React.createElement("label", null, "Suffix (for new model name):"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
value: suffix,
onChange: setSuffix
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
height: 5
}), /*#__PURE__*/React.createElement("small", null, "The name of the new model name will be decided by OpenAI. You can customize it a bit with a ", /*#__PURE__*/React.createElement("a", {
href: "https://platform.openai.com/docs/guides/fine-tuning/create-a-fine-tuned-model",
target: "_blank",
rel: "noreferrer"
}, "suffix"), ". Preview: ", /*#__PURE__*/React.createElement("b", null, modelNamePreview), "."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoSpacer, {
line: true,
height: 20
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_27__.NekoCheckbox, {
label: "Enable HyperParams",
checked: hyperParams,
onChange: setHyperParams
}), hyperParams && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement("label", {
style: {
marginRight: 5
}
}, "Number of Epochs:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
style: {
marginRight: 5
},
value: nEpochs,
onChange: setNEpochs,
type: "number"
}), /*#__PURE__*/React.createElement("label", {
style: {
marginRight: 5
}
}, "Batch Size:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
value: batchSize,
onChange: setBatchSize,
type: "number"
})), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement("label", {
style: {
marginRight: 5
}
}, "Learning Rate Multiplier:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
style: {
marginRight: 5
},
value: learningRateMultiplier,
onChange: setLearningRateMultiplier,
type: "number"
}), /*#__PURE__*/React.createElement("label", {
style: {
marginRight: 5
}
}, "Prompt Loss Weight:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_14__.NekoInput, {
value: promptLossWeight,
onChange: setPromptLossWeight,
type: "number"
}))))
})));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Finetunes);
/***/ }),
/***/ "./app/js/screens/finetunes/Generator.js":
/*!***********************************************!*\
!*** ./app/js/screens/finetunes/Generator.js ***!
\***********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Progress.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/hooks.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* eslint-disable no-undef */
/* eslint-disable no-console */
// React & Vendor Libs
const {
useState,
useRef
} = wp.element;
// NekoUI
const Generator = ({
instructions,
setMessages
}) => {
const [postType, setPostType] = useState('post');
const [totalTokens, setTotalTokens] = useState(0);
const [quickBusy, setQuickBusy] = useState(false);
const [generatePrompt, setGeneratePrompt] = useState("Generate 30 questions and answers from this text. Questions use a neutral tone. Answers use the same tone as the text.");
const suffixPrompt = "\n\nUse this format:\n\nQ: Question?\nA: Answer.\n\nQ: Question?\nA: Answer.\nText:\n\n{CONTENT}";
const abortController = useRef();
const {
isLoading: isLoadingPostTypes,
data: postTypes
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__.useQuery)({
queryKey: ['postTypes'],
queryFn: _app_requests__WEBPACK_IMPORTED_MODULE_1__.retrievePostTypes
});
const {
isLoading: isLoadingCount,
data: postsCount
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_0__.useQuery)({
queryKey: ['postsCount-' + postType],
queryFn: () => (0,_app_requests__WEBPACK_IMPORTED_MODULE_1__.retrievePostsCount)(postType)
});
const bulkTasks = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.useNekoTasks)({
i18n: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"],
onStop: () => {
setQuickBusy();
bulkTasks.reset();
}
});
const isBusy = quickBusy || bulkTasks.busy || isLoadingCount || isLoadingPostTypes;
const createEntriesFromRaw = rawData => {
if (!rawData) {
return [];
}
// Split the rawData by newline characters and filter out lines that only have whitespace
const arr = rawData.split("\n").filter(line => line.trim() !== "");
const entries = [];
let messages = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i].startsWith("Q:")) {
if (messages.length) {
// This handles consecutive questions without answers
entries.push({
messages: [...messages]
});
messages = [];
}
messages.push({
role: 'system',
content: instructions
});
messages.push({
role: 'user',
content: arr[i].slice(2).trim()
});
} else if (arr[i].startsWith("A:")) {
messages.push({
role: 'assistant',
content: arr[i].slice(2).trim()
});
entries.push({
messages: [...messages]
});
messages = []; // reset messages for the next pair
}
}
// This is to handle the scenario where the rawData ends with a question without an answer
if (messages.length) {
entries.push({
messages
});
}
return entries;
};
const runProcess = async (offset = 0, postId = undefined, signal = undefined) => {
let finalPrompt = generatePrompt + suffixPrompt;
const resContent = await (0,_app_requests__WEBPACK_IMPORTED_MODULE_1__.retrievePostContent)(postType, offset, postId ? postId : undefined);
let error = null;
let rawData = null;
const content = resContent === null || resContent === void 0 ? void 0 : resContent.content;
const url = resContent === null || resContent === void 0 ? void 0 : resContent.url;
const title = resContent === null || resContent === void 0 ? void 0 : resContent.title;
let tokens = 0;
if (!resContent.success) {
alert(resContent.message);
error = resContent.message;
} else if (content.length < 64) {
console.log("Issue: Content is too short! Skipped.", {
content
});
} else {
var _res$usage;
finalPrompt = finalPrompt.replace('{CONTENT}', content);
finalPrompt = finalPrompt.replace('{URL}', url);
finalPrompt = finalPrompt.replace('{TITLE}', title);
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_4__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_5__.apiUrl}/ai/completions`, {
method: 'POST',
json: {
scope: 'admin-tools',
session: _app_settings__WEBPACK_IMPORTED_MODULE_5__.session,
message: finalPrompt
},
signal: signal,
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_5__.restNonce
});
if (!res.success) {
var _res$error;
if ((_res$error = res.error) !== null && _res$error !== void 0 && _res$error.cancelledByUser) {
return null;
}
console.error(res);
throw new Error(res.message ?? "Unknown error, check your console logs.");
}
rawData = res === null || res === void 0 ? void 0 : res.data;
if (res !== null && res !== void 0 && (_res$usage = res.usage) !== null && _res$usage !== void 0 && _res$usage.total_tokens) {
tokens = res.usage.total_tokens;
setTotalTokens(totalTokens => totalTokens + res.usage.total_tokens);
}
}
if (signal !== null && signal !== void 0 && signal.aborted) {
cancelledByUser();
}
const entries = createEntriesFromRaw(rawData);
const result = {
content,
prompt: finalPrompt,
rawData,
entries,
error,
tokens
};
console.log("Result:", result);
return result;
};
const cancelledByUser = () => {
console.log('User aborted.');
setBusy(false);
bulkTasks.reset();
};
const onRunClick = async () => {
setTotalTokens(0);
const offsets = Array.from(Array(postsCount).keys());
const startOffset = prompt("There are " + offsets.length + " entries. If you want to start from a certain entry offset, type it here. Otherwise, just press OK, and everything will be processed.");
const tasks = offsets.map(offset => async signal => {
var _result$entries;
console.log("Task " + offset);
if (startOffset && offset < startOffset) {
return {
success: true
};
}
const result = await runProcess(offset, null, signal);
//let result = { entries: [ { prompt: offset, completion: offset } ] }
if ((result === null || result === void 0 || (_result$entries = result.entries) === null || _result$entries === void 0 ? void 0 : _result$entries.length) > 0) {
setMessages(messages => [...messages, ...result.entries]);
}
return {
success: true
};
});
await bulkTasks.start(tasks);
setQuickBusy(false);
alert("All done!");
bulkTasks.reset();
};
const onSingleGenerateClick = async () => {
try {
setTotalTokens(0);
const postId = prompt("Enter the ID of a post (leave blank to use the very first one).");
if (postId === null) {
return;
}
setQuickBusy('singleGenerate');
abortController.current = new AbortController();
const result = await runProcess(0, postId, abortController.current.signal);
if (!result.entries.length) {
alert("No entries were generated. Check the console for more information.");
} else {
const confirmAdd = confirm(`Got ${result.entries.length} entries! Do you want to add them to your data? If not, they will be displayed in your console.`);
if (confirmAdd) {
setMessages(messages => [...messages, ...result.entries]);
}
}
} catch (e) {
console.error(e);
alert(e.message);
} finally {
setQuickBusy(false);
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
width: '100%'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
disabled: isBusy,
onClick: onSingleGenerateClick,
isBusy: quickBusy === 'singleGenerate'
}, _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SINGLE_GENERATE), /*#__PURE__*/React.createElement("span", {
style: {
color: '#d1e8f2',
fontSize: '22px',
padding: 5
}
}, "|"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
disabled: isBusy,
onClick: () => onRunClick()
}, "Bulk Generate"), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: 10
}
}, "Based on ", isLoadingCount && '...', !isLoadingCount && postsCount), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSelect, {
id: "postType",
scrolldown: true,
disabled: isBusy,
name: "postType",
style: {
width: 100,
marginLeft: 10
},
onChange: setPostType,
value: postType
}, postTypes === null || postTypes === void 0 ? void 0 : postTypes.map(postType => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoOption, {
key: postType.type,
value: postType.type,
label: postType.name
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoProgress, {
busy: bulkTasks.busy,
style: {
marginLeft: 10,
flex: 'auto'
},
value: bulkTasks.value,
max: bulkTasks.max,
onStopClick: bulkTasks.stop
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: 10
}
}, "Tokens: ", totalTokens)), /*#__PURE__*/React.createElement("div", {
style: {
width: '100%'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoTextArea, {
id: "generatePrompt",
name: "generatePrompt",
rows: 2,
style: {
marginTop: 10,
marginBottom: 5
},
value: generatePrompt,
onBlur: setGeneratePrompt,
disabled: isBusy
})), bulkTasks.TasksErrorModal);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Generator);
/***/ }),
/***/ "./app/js/screens/misc/Moderation.js":
/*!*******************************************!*\
!*** ./app/js/screens/misc/Moderation.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useState
} = wp.element;
// NekoUI
const Moderation = ({
options,
updateOption,
busy: busyParent
}) => {
const [content, setContent] = useState('I would love to live on a tropical island with beautiful and sexy felines, where we could bask in the sun on the sandy beaches, sip on refreshing coconut milk, and enjoy each other\'s company. While we might occasionally fight in the trees, our days would mostly be spent in peaceful slumber. However, I am not sure of how we would handle any potential disruptions to our idyllic existence if human were to come...');
const [results, setResults] = useState([]);
const [error, setError] = useState('');
const [busy, setBusy] = useState(false);
const chatbot_moderation = options === null || options === void 0 ? void 0 : options.chatbot_moderation;
const isBusy = busy || busyParent;
const onModerateClick = async () => {
setBusy(true);
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/moderate`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
text: content
}
});
if (!res.success) {
setError(res.message);
} else {
let data = res.results;
setResults(data === null || data === void 0 ? void 0 : data.results);
}
setBusy(false);
};
const jsxChatbot = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.CHATBOT
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoCheckbox, {
name: "chatbot_moderation",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.ENABLE,
value: "1",
checked: chatbot_moderation,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].SETTINGS.CHATBOT_MODERATION_HELP,
onChange: updateOption
}));
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoBlock, {
busy: isBusy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_3__["default"].COMMON.SETTINGS,
className: "primary"
}, /*#__PURE__*/React.createElement("p", null, "You can enable moderation various parts of WordPress. It will slow down the processing a little."), jsxChatbot)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoBlock, {
busy: isBusy,
title: "AI Moderation Tester",
className: "primary"
}, /*#__PURE__*/React.createElement("p", null, "Paste a text below, and check if it is safe for your website. ", /*#__PURE__*/React.createElement("b", null, "OpenAI Moderation Model is free!"), " Learn more about it ", /*#__PURE__*/React.createElement("a", {
href: "https://platform.openai.com/docs/guides/moderation/overview",
target: "_blank"
}, "here"), "."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoTextArea, {
name: "context",
rows: 8,
value: content,
onChange: setContent
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoButton, {
fullWidth: true,
onClick: onModerateClick
}, "Moderation Check"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Results:"), /*#__PURE__*/React.createElement("pre", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoStringify)(results, 2))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Moderation);
/***/ }),
/***/ "./app/js/screens/misc/Search.js":
/*!***************************************!*\
!*** ./app/js/screens/misc/Search.js ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/table/Table.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
// React & Vendor Libs
const {
useState,
useMemo,
useEffect
} = wp.element;
// NekoUI
const Search = ({
options,
updateOption,
busy: settingsBusy
}) => {
const [query, setQuery] = useState('');
const [results, setResults] = useState(null);
const [multiResults, setMultiResults] = useState(null);
const [busy, setBusy] = useState(false);
// Check if embeddings module is enabled
const embeddingsEnabled = options === null || options === void 0 ? void 0 : options.module_embeddings;
// Get embeddings environments from options
const embeddingsEnvs = (options === null || options === void 0 ? void 0 : options.embeddings_envs) || [];
const onSearchWithMethod = async searchMethod => {
setBusy(true);
setResults(null);
setMultiResults(null);
try {
const payload = {
search: query,
method: searchMethod,
...(searchMethod === 'embeddings' && (options === null || options === void 0 ? void 0 : options.search_frontend_env_id) && {
envId: options.search_frontend_env_id
}),
...(searchMethod === 'keywords' && (options === null || options === void 0 ? void 0 : options.search_website_context) && {
websiteContext: options.search_website_context
})
};
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.restUrl}/mwai-ui/v1/search`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: payload
});
setResults(res);
} catch (error) {
console.error('Search error:', error);
setResults({
success: false,
message: error.message || 'An error occurred during search'
});
} finally {
setBusy(false);
}
};
const onMultiSearchClick = async () => {
setBusy(true);
setResults(null);
setMultiResults(null);
const methods = ['wordpress', 'keywords', 'embeddings'];
const searchResults = {};
try {
// Run all search methods
for (const searchMethod of methods) {
try {
const payload = {
search: query,
method: searchMethod,
...(searchMethod === 'embeddings' && (options === null || options === void 0 ? void 0 : options.search_frontend_env_id) && {
envId: options.search_frontend_env_id
}),
...(searchMethod === 'keywords' && (options === null || options === void 0 ? void 0 : options.search_website_context) && {
websiteContext: options.search_website_context
})
};
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.restUrl}/mwai-ui/v1/search`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: payload
});
searchResults[searchMethod] = res;
} catch (error) {
console.error(`${searchMethod} search error:`, error);
searchResults[searchMethod] = {
success: false,
message: error.message || `An error occurred during ${searchMethod} search`
};
}
}
setMultiResults(searchResults);
} finally {
setBusy(false);
}
};
// Format results for table display
const resultsData = useMemo(() => {
if (!(results !== null && results !== void 0 && results.results)) return [];
return results.results.map(post => ({
id: post.id,
title: post.title || 'Untitled',
excerpt: post.excerpt || 'No excerpt available',
score: post.score ? `${(post.score * 100).toFixed(0)}%` : null,
foundWith: post.found_with || null
}));
}, [results]);
const resultsColumns = useMemo(() => {
const cols = [{
accessor: 'title',
title: 'Title',
width: '200px'
}, {
accessor: 'excerpt',
title: 'Excerpt',
width: '100%'
}];
if ((results === null || results === void 0 ? void 0 : results.method) === 'embeddings') {
cols[1].width = '100%'; // excerpt takes all remaining space
cols.push({
accessor: 'score',
title: 'Score',
width: '80px'
});
} else if ((results === null || results === void 0 ? void 0 : results.method) === 'keywords') {
cols[1].width = '50%'; // excerpt takes 50%
cols.push({
accessor: 'score',
title: 'Score',
width: '80px'
});
cols.push({
accessor: 'foundWith',
title: 'Found with',
width: '50%'
});
}
return cols;
}, [results === null || results === void 0 ? void 0 : results.method]);
// Debug information display
const debugInfo = useMemo(() => {
if (!(results !== null && results !== void 0 && results.debug)) return null;
if ((results === null || results === void 0 ? void 0 : results.method) === 'embeddings') {
return /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10,
padding: 10,
background: '#f0f0f0',
borderRadius: 4,
fontSize: 12
}
}, /*#__PURE__*/React.createElement("strong", null, "Debug Info:"), /*#__PURE__*/React.createElement("div", null, "Total vectors found: ", results.debug.total_vectors), /*#__PURE__*/React.createElement("div", null, "Filtered posts: ", results.debug.filtered_posts), /*#__PURE__*/React.createElement("div", null, "Min score threshold: ", results.debug.min_score), results.debug.sample_vectors && /*#__PURE__*/React.createElement("details", {
style: {
marginTop: 5
}
}, /*#__PURE__*/React.createElement("summary", null, "Sample vectors (first 5)"), /*#__PURE__*/React.createElement("pre", {
style: {
fontSize: 11,
marginTop: 5
}
}, JSON.stringify(results.debug.sample_vectors, null, 2))));
} else {
var _results$debug$keywor, _results$debug$keywor2, _results$debug$keywor3;
return /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10,
padding: 10,
background: '#f0f0f0',
borderRadius: 4,
fontSize: 12
}
}, results.debug.keyword_tiers && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Keyword Tiers Generated:"), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 10,
marginTop: 5
}
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Exact:"), " ", (_results$debug$keywor = results.debug.keyword_tiers.exact) === null || _results$debug$keywor === void 0 ? void 0 : _results$debug$keywor.join(', ')), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Contextual:"), " ", (_results$debug$keywor2 = results.debug.keyword_tiers.contextual) === null || _results$debug$keywor2 === void 0 ? void 0 : _results$debug$keywor2.join(', ')), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "General:"), " ", (_results$debug$keywor3 = results.debug.keyword_tiers.general) === null || _results$debug$keywor3 === void 0 ? void 0 : _results$debug$keywor3.join(', '))), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Progressive Search (", results.debug.total_searches, " attempts):"))), results.debug.searches && /*#__PURE__*/React.createElement("details", {
style: {
marginTop: 5
}
}, /*#__PURE__*/React.createElement("summary", null, "View search attempts"), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5,
fontSize: 11
}
}, results.debug.searches.map((search, index) => /*#__PURE__*/React.createElement("div", {
key: index,
style: {
marginBottom: 3
}
}, search.attempt, ". \"", search.keywords, "\" (score: ", search.score, "%) \u2192 ", search.found, " posts")))), results.debug.total_searches && /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5,
color: '#666'
}
}, results.results.length >= 3 ? `Stopped after finding ${results.results.length} results` : `Completed ${results.debug.total_searches} searches`));
}
}, [results]);
// Helper function to format results for any method
const formatResultsForMethod = (methodResults, methodName) => {
if (!(methodResults !== null && methodResults !== void 0 && methodResults.results)) return [];
return methodResults.results.map(post => ({
id: post.id,
title: post.title || 'Untitled',
excerpt: post.excerpt || 'No excerpt available',
score: post.score ? `${(post.score * 100).toFixed(0)}%` : null,
foundWith: post.found_with || null
}));
};
// Helper function to get columns for any method
const getColumnsForMethod = methodName => {
const cols = [{
accessor: 'title',
title: 'Title',
width: '200px'
}, {
accessor: 'excerpt',
title: 'Excerpt',
width: '100%'
}];
if (methodName === 'embeddings') {
cols[1].width = '100%'; // excerpt takes all remaining space
cols.push({
accessor: 'score',
title: 'Score',
width: '80px'
});
} else if (methodName === 'keywords') {
cols[1].width = '50%'; // excerpt takes 50%
cols.push({
accessor: 'score',
title: 'Score',
width: '80px'
});
cols.push({
accessor: 'foundWith',
title: 'Found with',
width: '50%'
});
}
return cols;
};
// Helper function to get debug info for any method
const getDebugInfoForMethod = (methodResults, methodName) => {
if (!(methodResults !== null && methodResults !== void 0 && methodResults.debug)) return null;
if (methodName === 'embeddings') {
return /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10,
padding: 10,
background: 'rgba(255,255,255,0.1)',
borderRadius: 4,
fontSize: 12
}
}, /*#__PURE__*/React.createElement("strong", null, "Debug Info:"), /*#__PURE__*/React.createElement("div", null, "Total vectors found: ", methodResults.debug.total_vectors), /*#__PURE__*/React.createElement("div", null, "Filtered posts: ", methodResults.debug.filtered_posts), /*#__PURE__*/React.createElement("div", null, "Min score threshold: ", methodResults.debug.min_score), methodResults.debug.sample_vectors && /*#__PURE__*/React.createElement("details", {
style: {
marginTop: 5
}
}, /*#__PURE__*/React.createElement("summary", null, "Sample vectors (first 5)"), /*#__PURE__*/React.createElement("pre", {
style: {
fontSize: 11,
marginTop: 5
}
}, JSON.stringify(methodResults.debug.sample_vectors, null, 2))));
} else if (methodName === 'keywords') {
var _methodResults$debug$, _methodResults$debug$2, _methodResults$debug$3;
return /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10,
padding: 10,
background: 'rgba(255,255,255,0.1)',
borderRadius: 4,
fontSize: 12
}
}, methodResults.debug.keyword_tiers && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("strong", null, "Keyword Tiers Generated:"), /*#__PURE__*/React.createElement("div", {
style: {
marginLeft: 10,
marginTop: 5
}
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Exact:"), " ", (_methodResults$debug$ = methodResults.debug.keyword_tiers.exact) === null || _methodResults$debug$ === void 0 ? void 0 : _methodResults$debug$.join(', ')), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Contextual:"), " ", (_methodResults$debug$2 = methodResults.debug.keyword_tiers.contextual) === null || _methodResults$debug$2 === void 0 ? void 0 : _methodResults$debug$2.join(', ')), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "General:"), " ", (_methodResults$debug$3 = methodResults.debug.keyword_tiers.general) === null || _methodResults$debug$3 === void 0 ? void 0 : _methodResults$debug$3.join(', '))), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 10
}
}, /*#__PURE__*/React.createElement("strong", null, "Progressive Search (", methodResults.debug.total_searches, " attempts):"))), methodResults.debug.searches && /*#__PURE__*/React.createElement("details", {
style: {
marginTop: 5
}
}, /*#__PURE__*/React.createElement("summary", null, "View search attempts"), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5,
fontSize: 11
}
}, methodResults.debug.searches.map((search, index) => /*#__PURE__*/React.createElement("div", {
key: index,
style: {
marginBottom: 3
}
}, search.attempt, ". \"", search.keywords, "\" (score: ", search.score, "%) \u2192 ", search.found, " posts")))), methodResults.debug.total_searches && /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5
}
}, methodResults.results.length >= 3 ? `Stopped after finding ${methodResults.results.length} results` : `Completed ${methodResults.debug.total_searches} searches`));
}
return null;
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoColumn, {
minimal: true,
style: {
flex: 2
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoBlock, {
title: "Search Test",
className: "primary"
}, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 15
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoInput, {
name: "query",
value: query,
onChange: setQuery,
onEnter: () => onSearchWithMethod((options === null || options === void 0 ? void 0 : options.search_frontend_method) || 'wordpress'),
placeholder: "Enter your search query...",
disabled: busy,
fullWidth: true
})), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
gap: 8,
marginBottom: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "primary",
onClick: () => onSearchWithMethod((options === null || options === void 0 ? void 0 : options.search_frontend_method) || 'wordpress'),
disabled: !query || busy,
isBusy: busy,
style: {
flex: 1
}
}, "Search")), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
gap: 8
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "secondary",
onClick: () => onSearchWithMethod('wordpress'),
disabled: !query || busy,
style: {
flex: 1
}
}, "WordPress"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "secondary",
onClick: () => onSearchWithMethod('keywords'),
disabled: !query || busy,
style: {
flex: 1
}
}, "AI Keywords"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "secondary",
onClick: () => onSearchWithMethod('embeddings'),
disabled: !query || busy || !embeddingsEnabled || embeddingsEnvs.length === 0,
style: {
flex: 1
}
}, "Embeddings"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
className: "secondary",
onClick: onMultiSearchClick,
disabled: !query || busy,
style: {
flex: 1
}
}, "Multi-Method"))), results && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoBlock, {
title: "Results",
className: "primary"
}, results.success === false && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoMessage, {
variant: "danger"
}, results.message, results.debug && /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5,
fontSize: 12
}
}, "Debug: ", results.debug)), results.success && /*#__PURE__*/React.createElement(React.Fragment, null, resultsData.length > 0 ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoTable, {
data: resultsData,
columns: resultsColumns,
onSelectRow: id => {
const url = `${window.location.origin}/?p=${id}`;
window.open(url, '_blank');
}
}) : /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'center',
padding: 20,
color: '#666'
}
}, "No results found for your search query."))), results && results.success && debugInfo && results.method !== 'wordpress' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoBlock, {
title: "Search Debugging",
className: "primary"
}, debugInfo), multiResults && !results && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTabs, {
inversed: true,
title: "Search Results",
style: {
padding: 8
}
}, Object.entries(multiResults).map(([methodName, methodResults]) => {
const formattedResults = formatResultsForMethod(methodResults, methodName);
const columns = getColumnsForMethod(methodName);
const debugInfo = getDebugInfoForMethod(methodResults, methodName);
const methodLabel = methodName === 'wordpress' ? 'WordPress' : methodName === 'keywords' ? 'AI Keywords' : 'Embeddings';
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTab, {
key: methodName,
title: methodLabel,
inversed: true
}, methodResults.success === false && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoMessage, {
variant: "danger"
}, methodResults.message, methodResults.debug && /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 5,
fontSize: 12
}
}, "Debug: ", methodResults.debug)), methodResults.success && /*#__PURE__*/React.createElement(React.Fragment, null, formattedResults.length > 0 ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoTable, {
data: formattedResults,
columns: columns,
onSelectRow: id => {
const url = `${window.location.origin}/?p=${id}`;
window.open(url, '_blank');
}
}) : /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'center',
padding: 20
}
}, "No results found for your search query."), debugInfo && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoSpacer, null), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "Search Debugging:"), debugInfo))));
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoColumn, {
minimal: true,
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoBlock, {
title: "Search Method",
className: "primary",
busy: settingsBusy
}, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 15
}
}, /*#__PURE__*/React.createElement("label", {
style: {
display: 'block',
marginBottom: 5,
fontWeight: 'bold'
}
}, "Frontend Search Method"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
name: "search_frontend_method",
value: (options === null || options === void 0 ? void 0 : options.search_frontend_method) || 'wordpress',
onChange: updateOption,
fullWidth: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "wordpress",
label: "WordPress"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "keywords",
label: "AI Keywords"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
value: "embeddings",
label: "Embeddings"
}))), /*#__PURE__*/React.createElement("div", {
style: {
padding: 10,
background: '#f9f9f9',
borderRadius: 4,
fontSize: 13
}
}, /*#__PURE__*/React.createElement("strong", null, "Frontend Search:"), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "This controls how search widgets and blocks work on your website frontend. The method selected above will be used for all frontend searches."), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "Use the buttons above to test different methods before applying them to the frontend."))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTabs, {
inversed: true,
title: "Settings",
style: {
marginTop: 10,
padding: 8
},
busy: settingsBusy
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTab, {
title: "WordPress",
inversed: true
}, /*#__PURE__*/React.createElement("div", {
style: {
padding: 10,
background: 'rgba(255,255,255,0.1)',
borderRadius: 4,
fontSize: 13
}
}, /*#__PURE__*/React.createElement("strong", null, "WordPress Method:"), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "Uses the standard WordPress search functionality without any AI enhancements. This searches for exact matches of your query in post titles and content."), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "Results are ordered by relevance as determined by WordPress's built-in search algorithm."))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTab, {
title: "AI Keywords",
inversed: true
}, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 15
}
}, /*#__PURE__*/React.createElement("label", {
style: {
display: 'block',
marginBottom: 5,
fontWeight: 'bold'
}
}, "Website Context"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTextArea, {
name: "search_website_context",
value: (options === null || options === void 0 ? void 0 : options.search_website_context) || 'This is a website with useful information and content.',
onBlur: updateOption,
rows: 3,
fullWidth: true,
description: "Describe what your website is about to help AI generate better search keywords."
})), /*#__PURE__*/React.createElement("div", {
style: {
padding: 10,
background: 'rgba(255,255,255,0.1)',
borderRadius: 4,
fontSize: 13
}
}, /*#__PURE__*/React.createElement("strong", null, "AI Keywords Method:"), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "Uses a smart progressive search algorithm optimized for WordPress search. Searches progressively from high to low precision using simple words that authors actually write in posts."))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTab, {
title: "Embeddings",
inversed: true
}, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 15
}
}, /*#__PURE__*/React.createElement("label", {
style: {
display: 'block',
marginBottom: 5,
fontWeight: 'bold'
}
}, "Embeddings Environment"), !embeddingsEnabled ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoMessage, {
variant: "warning",
style: {
fontSize: 13
}
}, "The Embeddings module is not enabled. Please enable it in the Settings under Modules.") : embeddingsEnvs.length > 0 ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSelect, {
name: "search_frontend_env_id",
value: (options === null || options === void 0 ? void 0 : options.search_frontend_env_id) || '',
onChange: updateOption,
fullWidth: true,
placeholder: "Select environment..."
}, embeddingsEnvs.map(env => /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoOption, {
key: env.id,
value: env.id,
label: env.name
}))) : /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoMessage, {
variant: "info",
style: {
fontSize: 13
}
}, "No embeddings environments configured. Please configure one in the Knowledge tab.")), /*#__PURE__*/React.createElement("div", {
style: {
padding: 10,
background: 'rgba(255,255,255,0.1)',
borderRadius: 4,
fontSize: 13
}
}, /*#__PURE__*/React.createElement("strong", null, "Embeddings Method:"), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "Your search query will be converted into embeddings and compared against your indexed content for semantic similarity. This provides more intelligent results based on meaning rather than exact keyword matches."), /*#__PURE__*/React.createElement("p", {
style: {
margin: '5px 0'
}
}, "Make sure you have content indexed in your selected embeddings environment."))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Search);
/***/ }),
/***/ "./app/js/screens/misc/Transcription.js":
/*!**********************************************!*\
!*** ./app/js/screens/misc/Transcription.js ***!
\**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _textea_json_viewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @textea/json-viewer */ "./node_modules/@textea/json-viewer/dist/index.mjs");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/TextArea.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
// React & Vendor Libs
const {
useState,
useEffect
} = wp.element;
// NekoUI
const Transcription = () => {
const [url, setUrl] = useState('');
const [content, setContent] = useState('');
const [message, setMessage] = useState('');
const [busy, setBusy] = useState(false);
const [tab, setTab] = useState('imageToText');
const [startTime, setStartTime] = useState(null);
useEffect(() => {
setUrl('');
setContent('');
setMessage('');
}, [tab]);
const transcribe = async (type = 'imageToText') => {
let finalApiUrl = "";
if (type === 'textToJSON') {
finalApiUrl = `${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/json`;
} else if (type === 'imageToText') {
finalApiUrl = `${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/transcribe_image`;
} else if (type === 'audioToText') {
finalApiUrl = `${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/ai/transcribe_audio`;
} else {
alert(`Unknown transcription type: ${type}`);
return;
}
setBusy(type);
setStartTime(Date.now());
try {
var _data$error;
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(finalApiUrl, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
json: {
url,
message
}
});
let data = res.data;
if (data !== null && data !== void 0 && (_data$error = data.error) !== null && _data$error !== void 0 && _data$error.message) {
alert(data.error.message);
} else {
setContent(data);
}
} catch (err) {
alert(err.message);
} finally {
setBusy(false);
setStartTime(null);
}
};
const onChangeTab = (_index, attr) => {
setTab(attr.key);
};
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
title: "Features",
className: "raw"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTabs, {
inversed: true,
onChange: onChangeTab
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_6__["default"].COMMON.IMAGE_TO_TEXT,
key: "imageToText"
}, /*#__PURE__*/React.createElement("label", null, "Image URL:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTextArea, {
name: "url",
rows: 2,
value: url,
onChange: setUrl
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Prompt:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTextArea, {
rows: 2,
value: message,
onChange: setMessage
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoButton, {
fullWidth: true,
style: {
height: 40
},
disabled: busy,
isBusy: busy === 'imageToText',
startTime: startTime,
onClick: () => {
transcribe('imageToText');
}
}, "Transcribe Image"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement("p", null, "If you are looking for beautiful images to play with this, here are some URLs: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://offbeatjapan.org"
}, "Offbeat Japan"), ", ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://unsplash.com"
}, "Unsplash"), ", ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://www.pexels.com"
}, "Pexels"), ".")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_6__["default"].COMMON.AUDIO_TO_TEXT,
key: "audioToText"
}, /*#__PURE__*/React.createElement("label", null, "Audio URL:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTextArea, {
name: "url",
rows: 2,
value: url,
onChange: setUrl
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Prompt:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTextArea, {
rows: 2,
value: message,
onChange: setMessage
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoButton, {
fullWidth: true,
style: {
height: 40
},
disabled: busy,
isBusy: busy === 'audioToText',
startTime: startTime,
onClick: () => {
transcribe('audioToText');
}
}, "Transcribe Audio")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_6__["default"].COMMON.PROMPT_TO_JSON,
key: "textToJSON"
}, /*#__PURE__*/React.createElement("label", null, "Prompt:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTextArea, {
rows: 2,
value: message,
onChange: setMessage
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoButton, {
fullWidth: true,
style: {
height: 40
},
disabled: busy,
isBusy: busy === 'textToJSON',
startTime: startTime,
onClick: () => {
transcribe('textToJSON');
}
}, "Query AI"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null), /*#__PURE__*/React.createElement("label", null, "Examples:"), /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, "\uD83D\uDC7D List the best science fiction books. Include the title, author, publication year, and a short synopsis."), /*#__PURE__*/React.createElement("li", null, "\uD83C\uDF8B Identify the most beautiful gardens in Japan. Provide the garden name, location (gps: [lng, lat]), best visiting season, and features."), /*#__PURE__*/React.createElement("li", null, "\uD83D\uDCB0 Identify the current top 10 richest individuals globally. For each person, include their name, estimated net worth, source of wealth, country of residence, and key tags (such as 'technology', 'retail', 'investor', etc.). Additionally, provide a brief description of their most notable business ventures or achievements."), /*#__PURE__*/React.createElement("li", null, "\uD83E\uDD81 Compile a list of significant archaeological discoveries in the last decade. Include the discovery, location, date, and significance.")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, null))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoBlock, {
title: "Transcription",
className: "primary"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSpacer, {
tiny: true
}), tab === 'textToJSON' && /*#__PURE__*/React.createElement(_textea_json_viewer__WEBPACK_IMPORTED_MODULE_0__.JsonViewer, {
value: content,
indentWidth: 2,
displayDataTypes: false,
displayObjectSize: false,
displayArrayKey: false,
enableClipboard: false,
style: {
fontSize: 12
}
}), tab !== 'textToJSON' && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoTextArea, {
name: "context",
rows: 21,
value: content,
disabled: !content
}))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Transcription);
/***/ }),
/***/ "./app/js/screens/orchestration/MCPServers.js":
/*!****************************************************!*\
!*** ./app/js/screens/orchestration/MCPServers.js ***!
\****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/CollapsableCategory.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
// React & Vendor Libs
const {
useCallback,
useState
} = wp.element;
function MCPServersSettings({
options,
mcpServers,
updateMCPServer,
updateOption,
busy
}) {
const [validationErrors, setValidationErrors] = useState({});
const validateUniqueName = (name, currentId) => {
return !mcpServers.some(server => server.name === name && server.id !== currentId);
};
const addNewMCPServer = () => {
const baseName = 'New MCP Server';
let counter = 1;
let newName = baseName;
// Find a unique name
while (mcpServers.some(server => server.name === newName)) {
newName = `${baseName} ${counter}`;
counter++;
}
const newServer = {
name: newName,
type: 'url',
url: '',
token: ''
};
const updatedServers = [...mcpServers, newServer];
updateOption(updatedServers, 'mcp_envs');
};
const deleteMCPServer = id => {
if (mcpServers.length === 1) {
alert("You can't delete the last MCP server.");
return;
}
const updatedServers = mcpServers.filter(server => server.id !== id);
updateOption(updatedServers, 'mcp_envs');
};
const handleNameChange = useCallback((serverId, value) => {
if (!validateUniqueName(value, serverId)) {
setValidationErrors(prev => ({
...prev,
[serverId]: 'Name must be unique'
}));
return;
}
setValidationErrors(prev => {
const newErrors = {
...prev
};
delete newErrors[serverId];
return newErrors;
});
updateMCPServer(serverId, {
name: value
});
}, [mcpServers, updateMCPServer]);
const handleURLChange = useCallback((serverId, value) => {
updateMCPServer(serverId, {
url: value
});
}, [updateMCPServer]);
const handleTokenChange = useCallback((serverId, value) => {
updateMCPServer(serverId, {
token: value
});
}, [updateMCPServer]);
return /*#__PURE__*/React.createElement("div", {
style: {
padding: '0px 10px 5px 10px',
marginTop: 13,
marginBottom: 5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_0__.NekoTypo, {
h2: true,
style: {
color: 'white',
marginBottom: 15
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.MCP_SERVERS), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTabs, {
inversed: true,
style: {
marginTop: -5
},
action: /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton, {
rounded: true,
className: "secondary",
icon: "plus",
onClick: addNewMCPServer
})
}, mcpServers.map(server => {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTab, {
key: server.id,
title: server.name,
busy: busy
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.NAME
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "name",
value: server.name,
error: validationErrors[server.id],
description: "The name must be unique across all MCP servers",
onFinalChange: value => handleNameChange(server.id, value)
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.URL
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "url",
value: server.url,
placeholder: "https://example.com/mcp-server",
description: (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].HELP.MCP_SERVER_URL),
onFinalChange: value => handleURLChange(server.id, value)
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.TOKEN
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoInput, {
name: "token",
value: server.token,
placeholder: "Bearer token for authentication",
description: (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].HELP.MCP_SERVER_TOKEN),
onFinalChange: value => handleTokenChange(server.id, value)
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordions, {
keepState: "mcpServerCategories"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.SERVER_ID
}, /*#__PURE__*/React.createElement("p", null, "The Server ID is \"", /*#__PURE__*/React.createElement("b", null, server.id), "\".")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoAccordion, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.ACTIONS
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
marginTop: 10
}
}, /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton, {
className: "danger",
onClick: () => deleteMCPServer(server.id)
}, _root_i18n__WEBPACK_IMPORTED_MODULE_1__["default"].COMMON.DELETE)))));
})));
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MCPServersSettings);
/***/ }),
/***/ "./app/js/screens/queries/Insights.js":
/*!********************************************!*\
!*** ./app/js/screens/queries/Insights.js ***!
\********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var chart_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! chart.js */ "./node_modules/chart.js/dist/chart.js");
/* harmony import */ var react_chartjs_2__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! react-chartjs-2 */ "./node_modules/react-chartjs-2/dist/index.js");
/* harmony import */ var _textea_json_viewer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @textea/json-viewer */ "./node_modules/@textea/json-viewer/dist/index.mjs");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @app/helpers-admin */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Spacer.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Links.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Select.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/NekoUI.js");
/* harmony import */ var _app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @app/styles/StyledSidebar */ "./app/js/styles/StyledSidebar.js");
/* harmony import */ var _app_screens_queries_Queries__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @app/screens/queries/Queries */ "./app/js/screens/queries/Queries.js");
// React & Vendor Libs
const {
useMemo,
useState
} = wp.element;
chart_js__WEBPACK_IMPORTED_MODULE_0__.Chart.register(chart_js__WEBPACK_IMPORTED_MODULE_0__.CategoryScale, chart_js__WEBPACK_IMPORTED_MODULE_0__.LinearScale, chart_js__WEBPACK_IMPORTED_MODULE_0__.BarElement, chart_js__WEBPACK_IMPORTED_MODULE_0__.Tooltip, chart_js__WEBPACK_IMPORTED_MODULE_0__.Legend);
// NekoUI
/**
* Fetch meta for a single log (query, reply, fields).
*/
const retrieveLogsMeta = async logId => {
if (!logId) return null;
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_3__.apiUrl}/system/logs/meta`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_3__.restNonce,
method: 'POST',
json: {
logId,
metaKeys: ['query', 'reply', 'fields'] // only these from meta
}
});
return res.data;
};
const Insights = ({
options,
updateOption,
busy
}) => {
var _limits$users;
// All logs currently loaded from Queries.js
const [logs, setLogs] = useState([]);
// We rely on QueriesExplorer for multi-selection,
// but only one log can be "inspected" at a time in the tabs
const [selectedLogIds, setSelectedLogIds] = useState([]);
// Limits stuff
const [limitSection, setLimitSection] = useState('users');
const limits = options === null || options === void 0 ? void 0 : options.limits;
const default_limits = options === null || options === void 0 ? void 0 : options.default_limits;
// This figure out if exactly 1 log is selected
const logId = useMemo(() => selectedLogIds.length === 1 ? selectedLogIds[0] : null, [selectedLogIds]);
// The "main" log object from the logs array
// so we can get .stats (or other top-level fields)
const selectedLog = useMemo(() => {
const log = logs.find(l => l.id === logId);
if (log && log.stats && typeof log.stats === 'string') {
try {
log.stats = JSON.parse(log.stats);
} catch (e) {
log.stats = {};
}
}
return log;
}, [logs, logId]);
// Fetch the meta (Query/Reply/Fields) if we have exactly 1 log selected
const {
isFetching: isFetchingMeta,
data: metaData
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__.useQuery)({
queryKey: ['logsMeta', logId],
queryFn: () => retrieveLogsMeta(logId),
enabled: !!logId,
// only fetch if we have a valid ID
staleTime: 1000 * 60 * 60 * 24
});
const {
colors
} = (0,_neko_ui__WEBPACK_IMPORTED_MODULE_5__.useNekoColors)();
const {
models,
getModel
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.useModels)(options, null, true);
// Fetch activity data grouped by model
const {
data: activityByModel
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__.useQuery)({
queryKey: ['logsActivityDailyByModel'],
queryFn: () => (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_6__.retrieveLogsActivityDaily)(31, true),
staleTime: 1000 * 60 * 60 // Cache for 1 hour since daily data doesn't change as frequently
});
const activityChart = useMemo(() => {
if (!activityByModel || activityByModel.length === 0) return null;
// Generate labels for each day
const labels = activityByModel.map((_, idx) => {
const d = new Date();
d.setDate(d.getDate() - (activityByModel.length - 1 - idx));
return d.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric'
});
});
// If we don't have models info yet, show simple chart
if (!models || models.length === 0) {
// Calculate total for each day
const totals = activityByModel.map(dayData => {
return Object.values(dayData).reduce((sum, count) => sum + count, 0);
});
return {
labels,
datasets: [{
label: 'Queries',
data: totals,
backgroundColor: colors.blue
}]
};
}
// Extract unique models and map to families
const modelToFamily = {};
const families = new Set();
activityByModel.forEach(dayData => {
Object.keys(dayData).forEach(modelId => {
if (!modelToFamily[modelId]) {
const model = getModel(modelId);
const family = (model === null || model === void 0 ? void 0 : model.family) || 'Unknown';
modelToFamily[modelId] = family;
families.add(family);
}
});
});
// Define colors for families
const fixedColors = [colors.blue, colors.green, colors.yellow, colors.orange, colors.red, colors.purple];
const familyColors = {};
const sortedFamilies = Array.from(families).sort();
sortedFamilies.forEach((family, index) => {
familyColors[family] = fixedColors[index % fixedColors.length];
});
// Create datasets for each family
const datasets = sortedFamilies.map(family => {
const data = activityByModel.map(dayData => {
let count = 0;
Object.entries(dayData).forEach(([modelId, modelCount]) => {
if (modelToFamily[modelId] === family) {
count += modelCount;
}
});
return count;
});
return {
label: family,
data: data,
backgroundColor: familyColors[family]
};
});
return {
labels,
datasets
};
}, [activityByModel, colors, models, getModel]);
// Helper for building new "limits"
const updateLimits = async (value, id) => {
const newParams = {
...limits,
[id]: value
};
await updateOption(newParams, 'limits');
};
const limitSectionParams = useMemo(() => {
return limits !== null && limits !== void 0 && limits[limitSection] ? limits[limitSection] : {
credits: 1,
creditType: 'price',
timeFrame: 'month',
isAbsolute: false,
overLimitMessage: 'You have reached the limit.',
ignoredUsers: ''
};
}, [limits, limitSection]);
const updateLimitSection = async (value, id) => {
if (id === 'credits') {
value = Math.max(0, value);
}
const newParams = {
...limitSectionParams,
[id]: value
};
const newLimits = {
...limits,
[limitSection]: newParams
};
await updateOption(newLimits, 'limits');
};
const onResetLimits = async () => {
if (confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].ALERTS.ARE_YOU_SURE)) {
await updateOption(default_limits, 'limits');
}
};
// We only need metaData if it's NOT an array
const meta = useMemo(() => {
if (Array.isArray(metaData)) {
return null;
}
return metaData;
}, [metaData]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoColumn, {
minimal: true,
style: {
flex: 2.5
}
}, /*#__PURE__*/React.createElement(_app_screens_queries_Queries__WEBPACK_IMPORTED_MODULE_9__["default"], {
selectedLogIds: selectedLogIds,
setSelectedLogIds: setSelectedLogIds,
onDataFetched: setLogs // <-- We'll capture logs in our local state
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoColumn, {
minimal: true
}, logId && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSpacer, {
large: true
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTabs, {
inversed: true,
style: {
marginRight: 10,
marginLeft: 10
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.QUERY
}, /*#__PURE__*/React.createElement("div", {
style: {
height: 380,
overflow: 'auto',
maxHeight: 380
}
}, isFetchingMeta && /*#__PURE__*/React.createElement("i", {
style: {
color: 'gray'
}
}, "Loading..."), !isFetchingMeta && !meta && /*#__PURE__*/React.createElement("i", {
style: {
color: 'gray'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.DATA_NOT_AVAILABLE), !isFetchingMeta && meta && /*#__PURE__*/React.createElement(_textea_json_viewer__WEBPACK_IMPORTED_MODULE_1__.JsonViewer, {
value: meta['query'],
rootName: "query",
indentWidth: 2,
displayDataTypes: false,
displayObjectSize: false,
displayArrayKey: false,
enableClipboard: false,
style: {
fontSize: 12
}
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTab, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.REPLY
}, /*#__PURE__*/React.createElement("div", {
style: {
height: 380,
overflow: 'auto',
maxHeight: 380
}
}, isFetchingMeta && /*#__PURE__*/React.createElement("i", {
style: {
color: 'gray'
}
}, "Loading..."), !isFetchingMeta && !meta && /*#__PURE__*/React.createElement("i", {
style: {
color: 'gray'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.DATA_NOT_AVAILABLE), !isFetchingMeta && meta && /*#__PURE__*/React.createElement(_textea_json_viewer__WEBPACK_IMPORTED_MODULE_1__.JsonViewer, {
value: meta['reply'],
rootName: "reply",
indentWidth: 2,
displayDataTypes: false,
displayObjectSize: false,
displayArrayKey: false,
enableClipboard: false,
style: {
fontSize: 12
}
}))), meta && meta['fields'] && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTab, {
title: "Fields"
}, /*#__PURE__*/React.createElement("div", {
style: {
height: 380,
overflow: 'auto',
maxHeight: 380
}
}, isFetchingMeta && /*#__PURE__*/React.createElement("i", {
style: {
color: 'gray'
}
}, "Loading..."), !isFetchingMeta && !meta && /*#__PURE__*/React.createElement("i", {
style: {
color: 'gray'
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.DATA_NOT_AVAILABLE), !isFetchingMeta && meta && /*#__PURE__*/React.createElement(_textea_json_viewer__WEBPACK_IMPORTED_MODULE_1__.JsonViewer, {
value: meta['fields'],
rootName: "fields",
indentWidth: 2,
displayDataTypes: false,
displayObjectSize: false,
displayArrayKey: false,
enableClipboard: false,
style: {
fontSize: 12
}
}))), (selectedLog === null || selectedLog === void 0 ? void 0 : selectedLog.stats) && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoTab, {
title: "Stats"
}, /*#__PURE__*/React.createElement("div", {
style: {
height: 380,
overflow: 'auto',
maxHeight: 380
}
}, /*#__PURE__*/React.createElement(_textea_json_viewer__WEBPACK_IMPORTED_MODULE_1__.JsonViewer, {
value: selectedLog.stats,
rootName: "stats",
indentWidth: 2,
displayDataTypes: false,
displayObjectSize: false,
displayArrayKey: false,
enableClipboard: false,
style: {
fontSize: 12
}
}))))), activityChart && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoBlock, {
className: "primary",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.ACTIVITY,
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(react_chartjs_2__WEBPACK_IMPORTED_MODULE_13__.Bar, {
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
x: {
stacked: true
},
y: {
stacked: true
}
}
},
data: activityChart
})))), /*#__PURE__*/React.createElement(_app_styles_StyledSidebar__WEBPACK_IMPORTED_MODULE_14__.StyledBuilderForm, {
style: {
marginTop: -25
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoBlock, {
className: "primary",
busy: busy,
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.LIMITS,
style: {
flex: 1
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoCheckbox, {
name: "enabled",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].STATISTICS.ENABLE_LIMITS,
checked: limits === null || limits === void 0 ? void 0 : limits.enabled,
value: "1",
onChange: updateLimits
}), (limits === null || limits === void 0 ? void 0 : limits.enabled) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoQuickLinks, {
value: limitSection,
busy: busy,
onChange: val => setLimitSection(val)
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.USERS,
value: "users",
disabled: !(limits !== null && limits !== void 0 && limits.enabled)
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.GUESTS,
value: "guests"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoLink, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.SYSTEM,
value: "system"
})), (limits === null || limits === void 0 ? void 0 : limits.target) === 'userId' && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, "Message for Guests:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoInput, {
id: "guestMessage",
name: "guestMessage",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
value: limits === null || limits === void 0 ? void 0 : limits.guestMessage,
onEnter: updateLimitSection,
onBlur: updateLimitSection
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.CREDITS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoInput, {
id: "credits",
name: "credits",
type: "number",
min: "0",
max: "1000000",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
value: limitSectionParams.credits,
onEnter: updateLimitSection,
onBlur: updateLimitSection
})), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.TYPE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoSelect, {
scrolldown: true,
id: "creditType",
name: "creditType",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
value: limitSectionParams.creditType,
onChange: updateLimitSection
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "queries",
id: "queries",
value: "queries",
label: "Queries"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "units",
id: "units",
value: "units",
label: "Tokens"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "price",
id: "price",
value: "price",
label: "Dollars"
})))), limitSectionParams.credits !== 0 && /*#__PURE__*/React.createElement("p", null, "If you want to apply variable amount of credits,", ' ', /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com/ai-engine/faq/#limits",
target: "_blank",
rel: "noreferrer"
}, "click here"), "."), limitSectionParams.credits !== 0 && limitSectionParams.creditType === 'price' && /*#__PURE__*/React.createElement("p", null, "The dollars represent the budget you spent through OpenAI."), limitSectionParams.credits === 0 && /*#__PURE__*/React.createElement("p", null, "Since there are no credits, the Message for No Credits Message will be displayed."), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.TIMEFRAME, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoSelect, {
scrolldown: true,
id: "timeFrame",
name: "timeFrame",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
value: limitSectionParams.timeFrame,
onChange: updateLimitSection
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "second",
id: "second",
value: "second",
label: "Second"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "minute",
id: "minute",
value: "minute",
label: "Minute"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "hour",
id: "hour",
value: "hour",
label: "Hour"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "day",
id: "day",
value: "day",
label: "Day"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "week",
id: "week",
value: "week",
label: "Week"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "month",
id: "month",
value: "month",
label: "Month"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "year",
id: "year",
value: "year",
label: "Year"
}))), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.ABSOLUTE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoCheckbox, {
name: "isAbsolute",
label: "Yes",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
checked: limitSectionParams.isAbsolute,
value: "1",
onChange: updateLimitSection
}))), limitSectionParams.isAbsolute && /*#__PURE__*/React.createElement("p", null, (0,_neko_ui__WEBPACK_IMPORTED_MODULE_2__.toHTML)(_root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].STATISTICS.ABSOLUTE_HELP)), /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].STATISTICS.NO_CREDITS_MESSAGE, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_17__.NekoInput, {
id: "overLimitMessage",
name: "overLimitMessage",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
value: limitSectionParams.overLimitMessage,
onEnter: updateLimitSection,
onBlur: updateLimitSection
}))), limitSection === 'users' && /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-row"
}, /*#__PURE__*/React.createElement("div", {
className: "mwai-builder-col"
}, /*#__PURE__*/React.createElement("label", null, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].STATISTICS.FULL_ACCESS_USERS, ":"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoSelect, {
scrolldown: true,
id: "ignoredUsers",
name: "ignoredUsers",
disabled: !(limits !== null && limits !== void 0 && limits.enabled),
value: limits === null || limits === void 0 || (_limits$users = limits.users) === null || _limits$users === void 0 ? void 0 : _limits$users.ignoredUsers,
description: "",
onChange: updateLimitSection
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "none",
id: "none",
value: "",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.NONE
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "editor",
id: "editor",
value: "administrator,editor",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.EDITORS_ADMINS
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_18__.NekoOption, {
key: "admin",
id: "admin",
value: "administrator",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.ADMINS_ONLY
})))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoSpacer, null), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_19__.NekoButton, {
fullWidth: true,
className: "danger",
onClick: onResetLimits
}, _root_i18n__WEBPACK_IMPORTED_MODULE_7__["default"].COMMON.RESET_LIMITS)))))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Insights);
/***/ }),
/***/ "./app/js/screens/queries/Queries.js":
/*!*******************************************!*\
!*** ./app/js/screens/queries/Queries.js ***!
\*******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/table/Table.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Paging.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
// React & Vendor Libs
const {
useMemo,
useState,
useEffect
} = wp.element;
// NekoUI
/**
* Columns definition for the logs table
*/
const logsColumns = [{
accessor: 'id',
visible: false
}, {
accessor: 'time',
title: 'Time',
width: '95px',
sortable: true
}, {
accessor: 'user',
title: 'User',
width: '100px',
filters: {
type: 'text',
description: 'Type a User ID, or an IP.'
}
}, {
accessor: 'scope',
title: 'Scope',
width: '100px',
filters: {
type: 'checkbox',
options: [{
value: 'chatbot',
label: 'Chatbot'
}, {
value: 'form',
label: 'Form'
}, {
value: 'playground',
label: 'Playground'
}]
}
}, {
accessor: 'model',
title: 'Model',
width: '100%'
}, {
accessor: 'units',
title: 'Units',
width: '75px',
align: 'right',
sortable: true
}, {
accessor: 'price',
title: 'Price',
width: '95px',
align: 'right',
sortable: true
}, {
accessor: 'accuracy',
title: '',
width: '20px',
align: 'center'
}];
/**
* Fetch logs from the server.
*/
const retrieveLogs = async logsQueryParams => {
const params = {
...logsQueryParams,
offset: (logsQueryParams.page - 1) * logsQueryParams.limit
};
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/system/logs/list`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
method: 'POST',
json: params
});
// Check if there's an error in the response
if (res && res.success === false) {
throw new Error(res.message || 'Failed to retrieve logs');
}
return res ? {
total: res.total,
logs: res.logs
} : {
total: 0,
logs: []
};
};
/**
* Delete logs by ID (or all if none provided).
*/
const deleteLogs = async (logIds = []) => {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_0__.nekoFetch)(`${_app_settings__WEBPACK_IMPORTED_MODULE_1__.apiUrl}/system/logs/delete`, {
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_1__.restNonce,
method: 'POST',
json: {
logIds
}
});
return res;
};
/**
* Queries Explorer: shows the logs table, handles selection,
* and passes them back to the parent when fetched.
*/
const Queries = ({
selectedLogIds,
setSelectedLogIds,
onDataFetched // <--- NEW prop
}) => {
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_2__.useQueryClient)();
const [busyAction, setBusyAction] = useState(false);
const {
getModelName
} = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.useModels)(_app_settings__WEBPACK_IMPORTED_MODULE_1__.options, null, true);
// Filters for the logs table
const [filters, setFilters] = useState(() => logsColumns.filter(v => v.filters).map(v => {
return {
accessor: v.accessor,
value: []
};
}));
// Table query params
const [logsQueryParams, setLogsQueryParams] = useState({
filters,
sort: {
accessor: 'time',
by: 'desc'
},
page: 1,
limit: 20
});
// Main fetch of logs
const {
isFetching: isFetchingLogs,
data: logsData,
error: logsError
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__.useQuery)({
queryKey: ['logs', JSON.stringify(logsQueryParams)],
queryFn: () => retrieveLogs(logsQueryParams)
});
// Whenever filters changes, refresh the query params
useEffect(() => {
setLogsQueryParams({
...logsQueryParams,
filters
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filters]);
// If logsData changes and we have onDataFetched, pass the logs array up
useEffect(() => {
if (logsData !== null && logsData !== void 0 && logsData.logs && onDataFetched) {
onDataFetched(logsData.logs);
}
}, [logsData === null || logsData === void 0 ? void 0 : logsData.logs, onDataFetched]);
// Some memoized values
const logsTotal = useMemo(() => (logsData === null || logsData === void 0 ? void 0 : logsData.total) || 0, [logsData]);
const logsRows = useMemo(() => {
if (!(logsData !== null && logsData !== void 0 && logsData.logs)) {
return [];
}
return logsData.logs.sort((a, b) => b.created_at - a.created_at).map(x => {
var _options$ai_envs;
const time = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.tableDateTimeFormatter)(x.time);
const user = (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_3__.tableUserIPFormatter)(x.userId, x.ip);
const simplifiedPrice = Math.round(x.price * 1000) / 1000;
let jsxSimplifiedPrice = /*#__PURE__*/React.createElement("span", null, "$", simplifiedPrice.toFixed(4));
if (x.price >= 0.001) {
jsxSimplifiedPrice = /*#__PURE__*/React.createElement("b", null, "$", simplifiedPrice.toFixed(4));
}
if (x.price >= 0.01) {
jsxSimplifiedPrice = /*#__PURE__*/React.createElement("b", null, "$", simplifiedPrice.toFixed(2));
}
if (x.price >= 0.1) {
jsxSimplifiedPrice = /*#__PURE__*/React.createElement("b", {
style: {
fontWeight: 'bold'
}
}, "$", simplifiedPrice.toFixed(2));
}
// Let's round the price to 6 decimal places for display
const roundedPrice = Math.round(x.price * 1000000) / 1000000;
const jsxRoundedPrice = /*#__PURE__*/React.createElement("small", {
style: {
color: 'var(--neko-gray)'
}
}, "$", roundedPrice.toFixed(6));
const envName = (_app_settings__WEBPACK_IMPORTED_MODULE_1__.options === null || _app_settings__WEBPACK_IMPORTED_MODULE_1__.options === void 0 || (_options$ai_envs = _app_settings__WEBPACK_IMPORTED_MODULE_1__.options.ai_envs) === null || _options$ai_envs === void 0 || (_options$ai_envs = _options$ai_envs.find(v => v.id === x.envId)) === null || _options$ai_envs === void 0 ? void 0 : _options$ai_envs.name) || x.envId;
const model = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
title: x.model
}, getModelName(x.model, true), x.mode === 'assistant' && /*#__PURE__*/React.createElement("i", null, " (Assistant)")), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, envName));
// Create accuracy indicator
const accuracyColors = {
'none': 'var(--neko-gray-60)',
// Gray for unknown/old data
'estimated': 'var(--neko-orange)',
'tokens': 'var(--neko-yellow)',
'price': 'var(--neko-yellow)',
'full': 'var(--neko-green)'
};
const accuracyTitles = {
'none': 'Accuracy unknown (historical data)',
'estimated': 'Both values are estimated',
'tokens': 'Token count is accurate (from API), price is estimated',
'price': 'Price is accurate (from API), token count is estimated',
'full': 'Both token count and price are accurate (from API)'
};
const accuracy = x.accuracy || 'none';
const accuracyIndicator = /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'center'
},
title: accuracyTitles[accuracy]
}, /*#__PURE__*/React.createElement("div", {
style: {
width: '10px',
height: '10px',
borderRadius: '50%',
backgroundColor: accuracyColors[accuracy] || 'var(--neko-gray-60)',
margin: '0 auto'
}
}));
return {
id: x.id,
scope: /*#__PURE__*/React.createElement("div", null, x.scope, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", {
style: {
color: 'var(--neko-gray)'
}
}, x.session)),
user,
model,
units: /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'right'
}
}, x.units, /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, x.type)),
price: /*#__PURE__*/React.createElement(React.Fragment, null, jsxSimplifiedPrice, jsxRoundedPrice),
time: /*#__PURE__*/React.createElement("div", {
style: {
textAlign: 'right'
}
}, time),
accuracy: accuracyIndicator
};
});
}, [logsData]);
const onDeleteSelectedLogs = async () => {
setBusyAction(true);
if (!selectedLogIds.length) {
if (!window.confirm(_root_i18n__WEBPACK_IMPORTED_MODULE_5__["default"].ALERTS.ARE_YOU_SURE)) {
setBusyAction(false);
return;
}
await deleteLogs(); // delete all
} else {
await deleteLogs(selectedLogIds);
setSelectedLogIds([]);
}
await queryClient.invalidateQueries({
queryKey: ['logs']
});
setBusyAction(false);
};
const emptyMessage = useMemo(() => {
if (logsError !== null && logsError !== void 0 && logsError.message) {
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoMessage, {
variant: "danger",
style: {
margin: '5px 5px'
}
}, /*#__PURE__*/React.createElement("b", null, logsError.message), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, "Check your Console Logs and PHP Error Logs for more information."));
}
return null;
}, [logsError]);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoBlock, {
className: "primary",
title: _root_i18n__WEBPACK_IMPORTED_MODULE_5__["default"].COMMON.QUERY_LOGS,
action: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "secondary",
style: {
marginLeft: 5
},
disabled: isFetchingLogs,
onClick: async () => {
try {
await queryClient.invalidateQueries({
queryKey: ['logs']
});
} catch (error) {
// Error is handled by React Query
}
}
}, _root_i18n__WEBPACK_IMPORTED_MODULE_5__["default"].COMMON.REFRESH), selectedLogIds.length > 0 && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "danger",
onClick: onDeleteSelectedLogs
}, _root_i18n__WEBPACK_IMPORTED_MODULE_5__["default"].COMMON.DELETE))
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoTable, {
busy: isFetchingLogs || busyAction,
onSelectRow: id => {
// If the same row is clicked again, unselect it
if (selectedLogIds.length === 1 && selectedLogIds[0] === id) {
setSelectedLogIds([]);
} else {
setSelectedLogIds([id]);
}
},
onSelect: ids => {
setSelectedLogIds([...selectedLogIds, ...ids]);
},
onUnselect: ids => {
setSelectedLogIds(selectedLogIds.filter(x => !ids.includes(x)));
},
selectedItems: selectedLogIds,
sort: logsQueryParams.sort,
onSortChange: (accessor, by) => {
setLogsQueryParams({
...logsQueryParams,
sort: {
accessor,
by
}
});
},
emptyMessage: emptyMessage,
filters: filters,
onFilterChange: (accessor, value) => {
const freshFilters = [...filters.filter(x => x.accessor !== accessor), {
accessor,
value
}];
setFilters(freshFilters);
},
data: logsError ? [] : logsRows,
columns: logsColumns
}), /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
marginTop: 10,
marginBottom: -5
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoButton, {
className: "danger",
disabled: selectedLogIds.length > 0 // If something is selected, we show the other Delete button
,
onClick: onDeleteSelectedLogs
}, _root_i18n__WEBPACK_IMPORTED_MODULE_5__["default"].COMMON.DELETE_ALL), /*#__PURE__*/React.createElement("div", {
style: {
flex: 'auto'
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoPaging, {
currentPage: logsQueryParams.page,
limit: logsQueryParams.limit,
onCurrentPageChanged: page => setLogsQueryParams({
...logsQueryParams,
page
}),
total: logsTotal,
onClick: page => setLogsQueryParams({
...logsQueryParams,
page
})
}))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoBlock, {
className: "primary",
title: "Information"
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Prices and tokens counts aren't accurate in many cases.")), /*#__PURE__*/React.createElement("p", null, "For more information, check this:", ' ', /*#__PURE__*/React.createElement("a", {
href: "https://www.notion.so/meowarts/Cost-Usage-Calculation-d5ce4917d77f4939b232b20d0082368a?pvs=4",
target: "_blank",
rel: "noreferrer"
}, "Cost & Usage Calculation"), ". You are also always welcome to discuss about it in the", ' ', /*#__PURE__*/React.createElement("a", {
href: "https://discord.gg/bHDGh38",
target: "_blank",
rel: "noreferrer"
}, "Discord Server"), ".")));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Queries);
/***/ }),
/***/ "./app/js/screens/settings/DevToolsTab.js":
/*!************************************************!*\
!*** ./app/js/screens/settings/DevToolsTab.js ***!
\************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Log.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/helpers-admin */ "./app/js/helpers-admin.js");
/* harmony import */ var _app_requests__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @app/requests */ "./app/js/requests.js");
/* eslint-disable no-console */
// React & Vendor Libs
// const { useMemo, useState, useEffect } = wp.element;
// NekoUI
const DevToolsTab = ({
options,
updateOption,
setOptions,
busy
}) => {
const debug_mode = options === null || options === void 0 ? void 0 : options.debug_mode;
const module_mcp = options === null || options === void 0 ? void 0 : options.module_mcp;
const server_debug_mode = options === null || options === void 0 ? void 0 : options.server_debug_mode;
const mcp_debug_mode = options === null || options === void 0 ? void 0 : options.mcp_debug_mode;
const queries_debug_mode = options === null || options === void 0 ? void 0 : options.queries_debug_mode;
const dev_mode = options === null || options === void 0 ? void 0 : options.dev_mode;
const onGetContentClick = async () => {
const postId = prompt('Enter the Post ID you want to retrieve the content from.');
if (!postId) {
return;
}
const content = await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.retrievePostContent)(null, null, postId);
console.log(`Data for Post ID ${postId}`, content);
if (content !== null && content !== void 0 && content.content) {
const cleanContent = content.content.trim().replace(/<[^>]*>?/gm, '');
const firstWord = cleanContent.split(' ')[0];
const lastWord = cleanContent.split(' ').pop();
console.log(`Content First Word: ${firstWord}`);
console.log(`Content Last Word: ${lastWord}`);
}
};
const onRunTask = async () => {
await (0,_app_helpers_admin__WEBPACK_IMPORTED_MODULE_0__.runTasks)();
};
const jsxDevMode = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.DEV_MODE
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoCheckbox, {
name: "dev_mode",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
value: "1",
checked: dev_mode,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.DEV_MODE_HELP,
onChange: updateOption
}));
const jsxDebugMode = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CLIENT_DEBUG
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoCheckbox, {
name: "debug_mode",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
value: "1",
checked: debug_mode,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.CLIENT_DEBUG_HELP,
onChange: updateOption
}));
const jsxServerDebugMode = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SERVER_DEBUG
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoCheckbox, {
name: "server_debug_mode",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
value: "1",
checked: server_debug_mode,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.SERVER_DEBUG_HELP,
onChange: updateOption
}));
const jsxMcpDebugMode = module_mcp ? /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MCP_DEBUG
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoCheckbox, {
name: "mcp_debug_mode",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
value: "1",
checked: mcp_debug_mode,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.MCP_DEBUG_HELP,
onChange: updateOption
})) : null;
const jsxQueriesDebugMode = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoSettings, {
title: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.QUERIES_DEBUG
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoCheckbox, {
name: "queries_debug_mode",
label: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.ENABLE,
value: "1",
checked: queries_debug_mode,
description: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"].COMMON.QUERIES_DEBUG_HELP,
onChange: updateOption
}));
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoBlock, {
title: "Debugging",
className: "primary",
busy: busy
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
onClick: onGetContentClick
}, "Get Content"), /*#__PURE__*/React.createElement("p", null, "This button will display the content of the post, as seen by AI Engine, in your Developer Tools Console. That allows you to check what AI Engine uses when using Content Aware, Embeddings Sync, etc."), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
onClick: onRunTask
}, "Run Tasks"), /*#__PURE__*/React.createElement("p", null, "This button will force the AI Engine to run the tasks. Normally, the AI Engine runs the tasks every 10 minutes. This button will force the AI Engine to run the tasks immediately.")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoBlock, {
title: "Settings",
className: "primary",
busy: busy
}, jsxDevMode, /*#__PURE__*/React.createElement("h3", {
style: {
marginTop: 20,
marginBottom: 10
}
}, "Logs Console"), jsxDebugMode, jsxServerDebugMode, /*#__PURE__*/React.createElement("h3", {
style: {
marginTop: 20,
marginBottom: 10
}
}, "PHP Error Logs"), jsxMcpDebugMode, jsxQueriesDebugMode)), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoColumn, {
minimal: true
}, server_debug_mode && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoLog, {
refreshQuery: _app_requests__WEBPACK_IMPORTED_MODULE_8__.refreshLogs,
clearQuery: _app_requests__WEBPACK_IMPORTED_MODULE_8__.clearLogs,
i18n: _root_i18n__WEBPACK_IMPORTED_MODULE_2__["default"]
}))));
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (DevToolsTab);
/***/ }),
/***/ "./app/js/settings.js":
/*!****************************!*\
!*** ./app/js/settings.js ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ apiUrl: () => (/* binding */ apiUrl),
/* harmony export */ chatbots: () => (/* binding */ chatbots),
/* harmony export */ domain: () => (/* binding */ domain),
/* harmony export */ getRestNonce: () => (/* binding */ getRestNonce),
/* harmony export */ isPro: () => (/* binding */ isPro),
/* harmony export */ isRegistered: () => (/* binding */ isRegistered),
/* harmony export */ options: () => (/* binding */ options),
/* harmony export */ pluginUrl: () => (/* binding */ pluginUrl),
/* harmony export */ prefix: () => (/* binding */ prefix),
/* harmony export */ restNonce: () => (/* binding */ restNonce),
/* harmony export */ restUrl: () => (/* binding */ restUrl),
/* harmony export */ session: () => (/* binding */ session),
/* harmony export */ stream: () => (/* binding */ stream),
/* harmony export */ themes: () => (/* binding */ themes),
/* harmony export */ updateRestNonce: () => (/* binding */ updateRestNonce),
/* harmony export */ userData: () => (/* binding */ userData)
/* harmony export */ });
/* eslint-disable no-undef */
const prefix = mwai.prefix;
const domain = mwai.domain;
const restUrl = mwai.rest_url.replace(/\/+$/, "");
const apiUrl = mwai.api_url.replace(/\/+$/, "");
const pluginUrl = mwai.plugin_url.replace(/\/+$/, "");
const userData = mwai.user_data;
const isPro = mwai.is_pro === '1';
const isRegistered = isPro && mwai.is_registered === '1';
let restNonce = mwai.rest_nonce;
const options = mwai.options;
const session = mwai.session;
const themes = mwai.themes;
const stream = !!mwai.stream;
const chatbots = mwai.chatbots;
// Function to update the rest nonce globally
const updateRestNonce = newNonce => {
restNonce = newNonce;
// Also update it in the global mwai object
if (typeof mwai !== 'undefined') {
mwai.rest_nonce = newNonce;
}
};
// Function to get current rest nonce
const getRestNonce = () => restNonce;
/***/ }),
/***/ "./app/js/styles/AiIcon.js":
/*!*********************************!*\
!*** ./app/js/styles/AiIcon.js ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ AISVG: () => (/* binding */ AISVG),
/* harmony export */ WandSVG: () => (/* binding */ WandSVG),
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
const {
useState,
useEffect,
useMemo
} = wp.element;
const AISVG = /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
d: "m391 81h30v-66c0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m331 81h30v-66c0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m271 81h30v-66c0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m211 81h30v-66c0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15z",
fill: "#5f55af"
}), /*#__PURE__*/React.createElement("path", {
d: "m151 81h30v-66c0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15z",
fill: "#5f55af"
}), /*#__PURE__*/React.createElement("path", {
d: "m91 81h30v-66c0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15z",
fill: "#5f55af"
}), /*#__PURE__*/React.createElement("path", {
d: "m406 512c8.284 0 15-6.716 15-15v-66h-30v66c0 8.284 6.716 15 15 15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m346 512c8.284 0 15-6.716 15-15v-66h-30v66c0 8.284 6.716 15 15 15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m286 512c8.284 0 15-6.716 15-15v-66h-30v66c0 8.284 6.716 15 15 15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("g", {
fill: "#5f55af"
}, /*#__PURE__*/React.createElement("path", {
d: "m226 512c8.284 0 15-6.716 15-15v-66h-30v66c0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m166 512c8.284 0 15-6.716 15-15v-66h-30v66c0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m106 512c8.284 0 15-6.716 15-15v-66h-30v66c0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m15 121h66v-30h-66c-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m15 181h66v-30h-66c-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m15 241h66v-30h-66c-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m15 301h66v-30h-66c-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m15 361h66v-30h-66c-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"
}), /*#__PURE__*/React.createElement("path", {
d: "m15 421h66v-30h-66c-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"
})), /*#__PURE__*/React.createElement("path", {
d: "m431 91v30h66c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m431 181h66c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15h-66z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m431 241h66c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15h-66z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m431 301h66c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15h-66z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m431 361h66c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15h-66z",
fill: "#39326c"
}), /*#__PURE__*/React.createElement("path", {
d: "m431 421h66c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15h-66z",
fill: "#39326c"
})), /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
d: "m446 51h-380c-8.284 0-15 6.716-15 15v380c0 8.284 6.716 15 15 15h380c8.284 0 15-6.716 15-15v-380c0-8.284-6.716-15-15-15z",
fill: "#aed0ff"
}), /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
d: "m461 446v-380c0-8.284-6.716-15-15-15h-190v410h190c8.284 0 15-6.716 15-15z",
fill: "#7c84e8"
})), /*#__PURE__*/React.createElement("path", {
d: "m386 111h-260c-8.284 0-15 6.716-15 15v260c0 8.284 6.716 15 15 15h260c8.284 0 15-6.716 15-15v-260c0-8.284-6.716-15-15-15z",
fill: "#5f55af"
}), /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
d: "m401 386v-260c0-8.284-6.716-15-15-15h-130v290h130c8.284 0 15-6.716 15-15z",
fill: "#39326c"
}))), /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
d: "m247.626 192.389c-.052-.138-.106-.274-.162-.411-2.744-6.671-9.175-10.978-16.387-10.978-.006 0-.012 0-.018 0-7.219.007-13.65 4.329-16.383 11.01-.046.113-.091.227-.134.341l-45.06 118.31c-2.949 7.742.937 16.408 8.679 19.356 7.742 2.95 16.408-.937 19.356-8.679l7.543-19.804h51.691l7.458 19.762c2.267 6.007 7.974 9.708 14.036 9.708 1.76 0 3.55-.312 5.294-.97 7.75-2.925 11.663-11.579 8.737-19.33zm-31.14 79.146 14.538-38.171 14.406 38.171z",
fill: "#f9f9f9"
}), /*#__PURE__*/React.createElement("g", {
fill: "#e2dff4"
}, /*#__PURE__*/React.createElement("path", {
d: "m264.209 321.296c2.267 6.007 7.974 9.708 14.036 9.708 1.76 0 3.55-.312 5.294-.97 7.75-2.925 11.663-11.579 8.737-19.33l-36.276-96.126v86.956h.751z"
}), /*#__PURE__*/React.createElement("path", {
d: "m328.5 181c-8.284 0-15 6.716-15 15v120c0 8.284 6.716 15 15 15s15-6.716 15-15v-120c0-8.284-6.716-15-15-15z"
}))));
const WandSVG = /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
d: "m213.46 341.461-139.26 156.08c-16.17 18.48-44.53 19.33-61.8 2.06-17.32-17.32-16.37-45.67 2.06-61.8l156.08-139.26s13.46-2.54 29.46 13.46 13.46 29.46 13.46 29.46z",
fill: "#0052be"
}), /*#__PURE__*/React.createElement("path", {
d: "m213.46 341.461-139.26 156.08c-16.17 18.48-44.53 19.33-61.8 2.06l187.6-187.6c16 16 13.46 29.46 13.46 29.46z",
fill: "#00429b"
}), /*#__PURE__*/React.createElement("path", {
d: "m304 240.001-90.54 101.46c-14.997-14.997-27.922-27.922-42.92-42.92l101.46-90.54z",
fill: "#00429b"
}), /*#__PURE__*/React.createElement("path", {
d: "m304 240.001-90.54 101.46-21.46-21.46 96-96z",
fill: "#00337a"
}), /*#__PURE__*/React.createElement("path", {
d: "m400 279.001h-64.4l-42.47 57.87c-7.88 10.735-24.824 6.606-26.91-6.52l-11.56-73.01-73.01-11.56c-13.139-2.087-17.244-19.042-6.52-26.91l57.87-42.47v-64.4c0-12.176 13.797-19.289 23.72-12.21l50.15 35.83 70.92-19.9c11.25-3.168 21.656 7.245 18.49 18.49l-19.9 70.92 35.83 50.15c7.071 9.913-.02 23.72-12.21 23.72z",
fill: "#ffdd54"
}), /*#__PURE__*/React.createElement("path", {
d: "m412.21 255.281c7.071 9.913-.02 23.72-12.21 23.72h-64.4l-42.47 57.87c-7.875 10.728-24.823 6.616-26.91-6.52l-11.56-73.01 137.79-137.79c3.83 3.84 5.3 9.44 3.83 14.66l-19.9 70.92z",
fill: "#ffb454"
}), /*#__PURE__*/React.createElement("path", {
d: "m512 39.001c0 8.28-6.72 15-15 15h-9v9c0 8.28-6.72 15-15 15s-15-6.72-15-15v-9h-9c-8.28 0-15-6.72-15-15s6.72-15 15-15h9v-9c0-8.28 6.72-15 15-15s15 6.72 15 15v9h9c8.28 0 15 6.719 15 15z",
fill: "#bee75e"
}), /*#__PURE__*/React.createElement("path", {
d: "m512 39.001c0 8.28-6.72 15-15 15h-9v9c0 8.28-6.72 15-15 15s-15-6.72-15-15v-9l30-30h9c8.28 0 15 6.719 15 15z",
fill: "#00cb75"
}), /*#__PURE__*/React.createElement("path", {
d: "m336 41.001h-9v-9c0-8.284-6.716-15-15-15s-15 6.716-15 15v9h-9c-8.284 0-15 6.716-15 15s6.716 15 15 15h9v9c0 8.284 6.716 15 15 15s15-6.716 15-15v-9h9c8.284 0 15-6.716 15-15s-6.716-15-15-15z",
fill: "#f6f9f9"
}), /*#__PURE__*/React.createElement("path", {
d: "m441 224.001c0 8.284 6.716 15 15 15s15-6.716 15-15v-9h9c8.284 0 15-6.716 15-15s-6.716-15-15-15h-9v-9c0-8.284-6.716-15-15-15s-15 6.716-15 15v9h-9c-8.284 0-15 6.716-15 15s6.716 15 15 15h9z",
fill: "#e2dff4"
}), /*#__PURE__*/React.createElement("path", {
d: "m497 329.001h-9v-9c0-8.284-6.716-15-15-15s-15 6.716-15 15v9h-9c-8.284 0-15 6.716-15 15s6.716 15 15 15h9v9c0 8.284 6.716 15 15 15s15-6.716 15-15v-9h9c8.284 0 15-6.716 15-15s-6.716-15-15-15z",
fill: "#ff4a4a"
}), /*#__PURE__*/React.createElement("path", {
d: "m192 24.001h-9v-9c0-8.284-6.716-15-15-15s-15 6.716-15 15v9h-9c-8.284 0-15 6.716-15 15s6.716 15 15 15h9v9c0 8.284 6.716 15 15 15s15-6.716 15-15v-9h9c8.284 0 15-6.716 15-15s-6.716-15-15-15z",
fill: "#ff8659"
}), /*#__PURE__*/React.createElement("path", {
d: "m159.442 122.977-56-32c-7.191-4.109-16.355-1.611-20.466 5.581-4.11 7.193-1.611 16.355 5.581 20.466l56 32c7.16 4.093 16.337 1.644 20.466-5.581 4.111-7.193 1.612-16.355-5.581-20.466z",
fill: "#f6f9f9"
}), /*#__PURE__*/React.createElement("path", {
d: "m118.14 169.117-64 8c-8.221 1.027-14.052 8.524-13.023 16.744 1.027 8.218 8.523 14.054 16.744 13.023l64-8c8.221-1.027 14.052-8.524 13.023-16.744-1.028-8.22-8.527-14.062-16.744-13.023z",
fill: "#acceff"
}), /*#__PURE__*/React.createElement("path", {
d: "m389.023 352.558c-4.111-7.193-13.274-9.693-20.466-5.581-7.192 4.11-9.691 13.272-5.581 20.466l32 56c2.769 4.845 7.83 7.561 13.037 7.561 11.319 0 18.784-12.341 13.01-22.445z",
fill: "#e2dff4"
}), /*#__PURE__*/React.createElement("path", {
d: "m329.86 377.117c-8.222-1.031-15.717 4.804-16.744 13.023l-8 64c-1.117 8.925 5.834 16.862 14.902 16.862 7.455 0 13.917-5.553 14.865-13.142l8-64c1.029-8.219-4.802-15.716-13.023-16.743z",
fill: "#6ba7ff"
}));
const AiIcon = ({
icon = 'ai',
size = 20,
style = {}
} = {}) => {
const svgContent = useMemo(() => {
switch (icon) {
case 'ai':
return AISVG;
case 'wand':
return WandSVG;
default:
return AISVG;
}
}, [icon]);
return /*#__PURE__*/React.createElement("svg", {
style: {
width: size,
height: size,
marginRight: 5,
...style
},
"enable-background": "new 0 0 512 512",
height: "512",
viewBox: "0 0 512 512",
width: "512",
xmlns: "http://www.w3.org/2000/svg"
}, svgContent);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AiIcon);
/***/ }),
/***/ "./app/js/styles/CommonStyles.js":
/*!***************************************!*\
!*** ./app/js/styles/CommonStyles.js ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ AiButton: () => (/* binding */ AiButton),
/* harmony export */ AiNekoHeader: () => (/* binding */ AiNekoHeader),
/* harmony export */ StyledGallery: () => (/* binding */ StyledGallery),
/* harmony export */ StyledTitleWithButton: () => (/* binding */ StyledTitleWithButton)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Header.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _root_i18n__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @root/i18n */ "./app/i18n.js");
/* harmony import */ var _AiIcon__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./AiIcon */ "./app/js/styles/AiIcon.js");
const AiNekoHeader = ({
title = _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.SETTINGS,
options = _app_settings__WEBPACK_IMPORTED_MODULE_1__.options
}) => {
const module_playground = options === null || options === void 0 ? void 0 : options.module_playground;
const module_generator_content = options === null || options === void 0 ? void 0 : options.module_generator_content;
const module_generator_images = options === null || options === void 0 ? void 0 : options.module_generator_images;
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoHeader, {
title: `AI Engine | ${title}`
}, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'flex-end'
}
}, module_generator_content && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton, {
className: "header",
onClick: () => location.href = 'edit.php?page=mwai_content_generator'
}, /*#__PURE__*/React.createElement(_AiIcon__WEBPACK_IMPORTED_MODULE_4__["default"], {
icon: "wand",
style: {
marginRight: 8
}
}), _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.CONTENT), module_generator_images && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton, {
className: "header",
icon: "",
onClick: () => location.href = 'edit.php?page=mwai_images_generator'
}, /*#__PURE__*/React.createElement(_AiIcon__WEBPACK_IMPORTED_MODULE_4__["default"], {
icon: "wand",
style: {
marginRight: 8
}
}), _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.IMAGES), module_playground && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton, {
className: "header",
icon: "",
onClick: () => location.href = 'tools.php?page=mwai_dashboard'
}, /*#__PURE__*/React.createElement(_AiIcon__WEBPACK_IMPORTED_MODULE_4__["default"], {
icon: "wand",
style: {
marginRight: 8
}
}), _root_i18n__WEBPACK_IMPORTED_MODULE_0__["default"].COMMON.PLAYGROUND), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton, {
className: "header",
icon: "tools",
onClick: () => location.href = 'admin.php?page=mwai_settings'
})));
};
const AiButton = (0,styled_components__WEBPACK_IMPORTED_MODULE_5__["default"])((0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoButton))`
`;
const StyledTitleWithButton = styled_components__WEBPACK_IMPORTED_MODULE_5__["default"].div`
display: flex;
justify-content: unset;
align-items: center;
justify-content: space-between;
padding: 0 0 2px 0;
h2 {
margin: 7px 0 0 0;
padding: 0;
}
`;
const StyledGallery = styled_components__WEBPACK_IMPORTED_MODULE_5__["default"].div`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(30%, 1fr));
grid-template-rows: repeat(auto-fit, minmax(30%, 1fr));
grid-gap: 10px;
margin-top: 20px;
img, div {
width: 100%;
cursor: pointer;
}
.image-wrapper {
position: relative;
}
.delete-icon {
display: none;
position: absolute;
top: 5px;
right: 5px;
background: rgba(0,0,0,0.7);
color: #fff;
width: 20px;
height: 20px;
border-radius: 50%;
align-items: center;
justify-content: center;
font-size: 14px;
}
.image-wrapper:hover .delete-icon {
display: flex;
}
.media-label {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.6);
color: #fff;
text-align: center;
font-size: 12px;
padding: 2px 0;
text-decoration: underline;
cursor: pointer;
}
.empty-image {
width: 100%;
padding-bottom: 100%;
background-color: #f5f5f5;
}
`;
/***/ }),
/***/ "./app/js/styles/ModalStyles.js":
/*!**************************************!*\
!*** ./app/js/styles/ModalStyles.js ***!
\**************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Result: () => (/* binding */ Result),
/* harmony export */ ResultsContainer: () => (/* binding */ ResultsContainer)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
const ResultsContainer = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
margin-bottom: 5px;
`;
const Result = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
margin-top: 5px;
padding: 10px;
font-size: 14px;
cursor: pointer;
background: #dbf2ff;
&:hover {
background: #037cba;
color: white;
}
`;
/***/ }),
/***/ "./app/js/styles/StyledSidebar.js":
/*!****************************************!*\
!*** ./app/js/styles/StyledSidebar.js ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ StyledBuilderForm: () => (/* binding */ StyledBuilderForm),
/* harmony export */ StyledMainContentBlock: () => (/* binding */ StyledMainContentBlock),
/* harmony export */ StyledNekoInput: () => (/* binding */ StyledNekoInput),
/* harmony export */ StyledSidebar: () => (/* binding */ StyledSidebar),
/* harmony export */ StyledSidebarBlock: () => (/* binding */ StyledSidebarBlock)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
const StyledSidebar = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
background: white;
padding: 15px;
border-radius: 5px;
h2 {
margin-bottom: 8px;
}
h2:first-child, h3:first-child {
margin-top: 0;
}
label {
display: block;
margin-bottom: 5px;
}
label {
margin-top: 10px;
}
ul {
margin: 20px 0 0 0;
}
li {
margin-bottom: 5px;
border: 1px solid #e5e5e5;
padding: 8px;
background: #f5f5f5;
border-radius: 5px;
cursor: pointer;
position: relative;
&:last-child {
margin-bottom: 0;
}
&:hover {
background: #e5e5e5;
}
&.active {
background: #007cba;
color: white;
border-color: #007cba;
&.modified {
background: #ff8c00;
border-color: #ff8c00;
}
}
}
.information {
color: #a3a3a3;
margin-top: 5px;
font-size: 12px;
line-height: 100%;
}
`;
const StyledNekoInput = (0,styled_components__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoInput))`
flex: auto !important;
input {
height: 50px !important;
font-size: 13px !important;
font-family: monospace !important;
padding: 20px !important;
border-color: #333d4e !important;
background: #333d4e !important;
color: white !important;
}
`;
const StyledSidebarBlock = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
background: #fff;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
padding: 20px;
margin-bottom: 20px;
height: auto;
p {
margin: 10px 0;
color: #666;
font-size: 14px;
line-height: 1.5;
}
label {
font-weight: 600;
color: #333;
}
`;
const StyledMainContentBlock = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
background: #fff;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
padding: 20px;
height: auto;
min-height: 400px;
display: flex;
flex-direction: column;
.content-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h2 {
margin: 0;
font-size: 20px;
font-weight: 600;
color: #333;
}
}
.content-body {
flex: 1;
display: flex;
flex-direction: column;
}
`;
const StyledBuilderForm = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
display: flex;
flex-direction: column;
label {
margin-bottom: 3px;
}
.mwai-builder-row {
margin-top: 10px;
display: flex;
flex-direction: row;
.neko-color-picker {
margin-left: 5px;
}
}
.mwai-builder-col {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 5px;
}
.mwai-builder-col:last-child {
margin-right: 0;
}
pre {
white-space: pre-wrap;
background: #d4f0ff;
color: #037cba;
padding: 10px;
font-size: 13px;
font-weight: bold;
margin: 10px 0 10px 0;
}
.neko-spacer {
margin-bottom: 0 !important;
}
.neko-input {
}
.nui-select-option {
}
`;
/***/ }),
/***/ "./common/js/components/LicenseBlock.js":
/*!**********************************************!*\
!*** ./common/js/components/LicenseBlock.js ***!
\**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ LicenseBlock: () => (/* binding */ LicenseBlock)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Input.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Message.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/modal/Modal.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* eslint-disable no-undef */
// React & Vendor Libs
const {
useState,
useEffect
} = wp.element;
// NekoUI
// From Main Plugin
const CommonApiUrl = `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/meow-licenser/${_app_settings__WEBPACK_IMPORTED_MODULE_0__.prefix}/v1`;
const LicenseBlock = () => {
const [busy, setBusy] = useState(false);
const [meowMode, setMeowMode] = useState(false);
const [currentModal, setCurrentModal] = useState(null);
const [license, setLicense] = useState(null);
const [serialKey, setSerialKey] = useState('');
const isOverridenLicense = _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered && (!license || license.license !== 'valid');
const checkLicense = async () => {
if (!_app_settings__WEBPACK_IMPORTED_MODULE_0__.isPro) {
return;
}
setBusy(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${CommonApiUrl}/get_license`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce
});
setLicense(res.data);
if (res.data.key) {
setSerialKey(res.data.key);
}
} catch (err) {
alert('Error while checking the license. Check your console for more information.');
console.error(err);
}
setBusy(false);
};
const removeLicense = async () => {
setBusy(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${CommonApiUrl}/set_license`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce,
json: {
serialKey: null
}
});
if (res.success) {
setSerialKey('');
setLicense(null);
setCurrentModal('licenseRemoved');
}
} catch (err) {
alert('Error while removing the license. Check your console for more information.');
console.error(err);
}
setBusy(false);
};
const forceLicense = async () => {
setBusy(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${CommonApiUrl}/set_license`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce,
json: {
serialKey,
override: true
}
});
if (res.success) {
setLicense(res.data);
if (res.data && !res.data.issue) {
setCurrentModal('licenseAdded');
}
}
} catch (err) {
alert('Error while forcing the license. Check your console for more information.');
console.error(err);
}
setBusy(false);
};
const validateLicense = async () => {
if (serialKey === 'MEOW_OVERRIDE') {
setMeowMode(true);
setLicense(null);
setSerialKey("");
return;
}
setBusy(true);
try {
const res = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${CommonApiUrl}/set_license`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce,
json: {
serialKey
}
});
if (res.success) {
setLicense(res.data);
if (res.data && !res.data.issue) {
setCurrentModal('licenseAdded');
}
}
} catch (err) {
alert('Error while validating the license. Check your console for more information.');
console.error(err);
}
setBusy(false);
};
useEffect(() => {
checkLicense();
}, []);
const licenseTextStatus = isOverridenLicense ? 'Forced License' : _app_settings__WEBPACK_IMPORTED_MODULE_0__.isRegistered ? 'Enabled' : 'Disabled';
const success = isOverridenLicense || license && license.license === 'valid';
let message = 'Your license is active. Thanks a lot for your support :)';
if (isOverridenLicense) {
message = 'This license has been force-enabled for you.';
if (license && license.check_url) {
message = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, message), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("small", null, "To check your license status, please click ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: license.check_url + '&cache=' + Math.random() * 642000,
rel: "noreferrer"
}, "here"), "."));
}
}
if (!success) {
if (!license) {
message = 'Unknown error :(';
} else if (license.issue === 'no_activations_left') {
message = /*#__PURE__*/React.createElement("span", null, "There are no activations left for this license. You can visit your account at ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: "https://meowapps.com"
}, "Meow Apps"), ", unregister a site, and click on ", /*#__PURE__*/React.createElement("i", null, "Retry to validate"), ".");
} else if (license.issue === 'expired') {
message = /*#__PURE__*/React.createElement("span", null, "Your license has expired. You can get another license or renew the current one by visiting your account at ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: "https://meowapps.com"
}, "Meow Apps"), ".");
} else if (license.issue === 'missing') {
message = 'This license does not exist.';
} else if (license.issue === 'disabled') {
message = 'This license has been disabled.';
} else if (license.issue === 'item_name_mismatch') {
message = 'This license seems to be for a different plugin... isn\'t it? :)';
} else if (license.issue === 'forced') {
message = 'ABC';
} else {
message = /*#__PURE__*/React.createElement("span", null, "There is an unknown error related to the system or this serial key. Really sorry about this! Make sure your security plugins and systems are off temporarily. If you are still experiencing an issue, please ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: "https://meowapps.com/contact/"
}, "contact us"), ".");
console.error({
license
});
}
}
const jsxNonPro = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoBlock, {
title: "Pro Version (Not Installed)",
className: "primary"
}, "You will find more information about the Pro Version ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: `https://meowapps.com`
}, "here"), ". If you actually bought the Pro Version already, please remove the current plugin and download the Pro Version from your account at ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: "https://meowapps.com/"
}, "Meow Apps"), ".");
const jsxProVersion = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoBlock, {
title: `Pro Version (${licenseTextStatus})`,
busy: busy,
className: "primary"
}, !isOverridenLicense && !(license && license.key === serialKey) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
style: {
marginBottom: 10
}
}, "License Key:"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoInput, {
id: "mfrh_pro_serial",
name: "mfrh_pro_serial",
disabled: busy,
value: serialKey,
onChange: txt => setSerialKey(txt),
placeholder: "Type your license key..."
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoTypo, {
p: true
}, "Insert your serial key above. If you don't have one yet, you can get one ", /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com"
}, "here"), ". If there was an error during the validation, try the ", /*#__PURE__*/React.createElement("i", null, "Retry"), " to ", /*#__PURE__*/React.createElement("i", null, "validate"), " button.")), license && !success && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoMessage, {
variant: "danger"
}, message), (isOverridenLicense || license) && success && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoMessage, {
variant: "success"
}, message), /*#__PURE__*/React.createElement("div", {
style: {
marginTop: 15,
display: 'flex',
justifyContent: 'end'
}
}, license && !success && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
className: "secondary",
disabled: busy || !serialKey,
onClick: validateLicense
}, "Retry to validate"), license && license.key === serialKey && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
className: "secondary",
disabled: busy || !serialKey,
onClick: removeLicense
}, "Remove License"), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
disabled: busy || !serialKey || license && license.key === serialKey,
onClick: validateLicense
}, "Validate License"), meowMode && !success && /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_6__.NekoButton, {
disabled: busy || !serialKey || license && license.key === serialKey,
onClick: forceLicense,
className: "danger"
}, "Force License")), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoModal, {
isOpen: currentModal === 'licenseAdded',
title: "Thank you :)",
content: "The Pro features have been enabled. This page should be now reloaded.",
okButton: {
label: "Reload",
onClick: () => location.reload()
}
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoModal, {
isOpen: currentModal === 'licenseRemoved',
title: "Goodbye :(",
content: "The Pro features have been disabled. This page should be now reloaded.",
okButton: {
label: "Reload",
onClick: () => location.reload()
}
}));
return _app_settings__WEBPACK_IMPORTED_MODULE_0__.isPro ? jsxProVersion : jsxNonPro;
};
/***/ }),
/***/ "./common/js/dashboard/Dashboard.js":
/*!******************************************!*\
!*** ./common/js/dashboard/Dashboard.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Dashboard: () => (/* binding */ Dashboard)
/* harmony export */ });
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useQuery.js");
/* harmony import */ var _tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @tanstack/react-query */ "./node_modules/@tanstack/react-query/build/modern/useMutation.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Settings.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/CheckboxGroup.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/form/Checkbox.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Page.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Header.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Wrapper.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/tabs/Tabs.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _SpeedTester__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./SpeedTester */ "./common/js/dashboard/SpeedTester.js");
/* harmony import */ var _Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Dashboard.styled */ "./common/js/dashboard/Dashboard.styled.js");
/* eslint-disable react/no-unescaped-entities */
// React & Vendor Libs
const {
useState,
useEffect
} = wp.element;
// NekoUI
if (!_app_settings__WEBPACK_IMPORTED_MODULE_0__.apiUrl || !_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl || !_app_settings__WEBPACK_IMPORTED_MODULE_0__.pluginUrl) {
console.error("[@common/dashboard] apiUrl, restUrl and pluginUrl are mandatory.");
}
const CommonApiUrl = `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/meow-common/v1`;
const jsxTextStory = /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.TabText, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTypo, {
p: true,
style: {
lineHeight: '1.5',
margin: '0 0 15px 0'
}
}, "Hi! \u2600\uFE0F Meow Apps isn't your typical plugin suite\u2014it's a passion project led by me, ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: "https://jordymeow.com"
}, "Jordy Meow"), ", and a stellar team! \uD83D\uDC95 Based in ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
rel: "noreferrer",
href: "https://offbeatjapan.org"
}, "Japan"), ", we're all about making your WordPress experience smoother and speedier. Our plugins are all about boosting your site's performance and user-friendliness. Ready to level up your WordPress game? Check out ", /*#__PURE__*/React.createElement("a", {
href: "http://meowapps.com",
rel: "noreferrer",
target: "_blank"
}, "Meow Apps"), " and let's make magic happen! \uD83C\uDF34\uD83D\uDE40"));
const jsxTextPerformance = /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.TabText, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTypo, {
p: true
}, "The ", /*#__PURE__*/React.createElement("b", null, "Empty Request Time"), " measures your installation's basic performance by showing the average time needed to process an empty request on your server. To see how disabling plugins affects the results, turn some off and run the test again. Aim for a time under 2,000 ms, but ideally, keep it below 500 ms. The ", /*#__PURE__*/React.createElement("b", null, "File Operation Time"), " creates a temporary 10MB file each time it runs. ", /*#__PURE__*/React.createElement("b", null, "The SQL Request Time"), " calculates the total number of posts. This process should be quick and have a similar duration to the Empty Request Time."));
const jsxTextRecommendations = /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.TabText, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTypo, {
p: true
}, "Maintain a streamlined WordPress setup by using essential plugins and a dependable hosting provider. Refrain from self-hosting unless you're an expert. Go further by reading our tutorials:", /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, "\u2B50\uFE0F ", /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com/tutorial-improve-seo-wordpress/",
rel: "noreferrer",
target: "_blank"
}, "SEO Checklist & Optimization")), /*#__PURE__*/React.createElement("li", null, "\u2B50\uFE0F ", /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com/tutorial-faster-wordpress-optimize/",
rel: "noreferrer",
target: "_blank"
}, "Optimize your WordPress Speed")), /*#__PURE__*/React.createElement("li", null, "\u2B50\uFE0F ", /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com/tutorial-optimize-images-wordpress/",
rel: "noreferrer",
target: "_blank"
}, "Optimize Images (CDN, and so on)")), /*#__PURE__*/React.createElement("li", null, "\u2B50\uFE0F ", /*#__PURE__*/React.createElement("a", {
href: "https://meowapps.com/tutorial-hosting-service-wordpress/",
rel: "noreferrer",
target: "_blank"
}, "The Best Hosting Services for WordPress")))));
const fetchSettings = async () => {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${CommonApiUrl}/all_settings/`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce
});
return response.data;
};
const updateOption = async ({
value,
id
}) => {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${CommonApiUrl}/update_option`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce,
json: {
name: id,
value
}
});
return response;
};
const fetchErrorLogs = async () => {
const response = await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_3__.nekoFetch)(`${CommonApiUrl}/error_logs`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce
});
return response.data.reverse();
};
const Dashboard = () => {
const queryClient = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_4__.useQueryClient)();
const [fatalError, setFatalError] = useState(false);
const [phpInfo, setPhpInfo] = useState("");
const {
data: settings,
error: queryError
} = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_5__.useQuery)({
queryKey: ['all_settings'],
queryFn: fetchSettings
});
const updateOptionMutation = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__.useMutation)({
mutationFn: updateOption,
onSuccess: () => {
queryClient.invalidateQueries(['all_settings']);
}
});
const errorLogsMutation = (0,_tanstack_react_query__WEBPACK_IMPORTED_MODULE_6__.useMutation)({
mutationFn: fetchErrorLogs
});
const hide_meowapps = settings === null || settings === void 0 ? void 0 : settings.meowapps_hide_meowapps;
const force_sslverify = settings === null || settings === void 0 ? void 0 : settings.force_sslverify;
useEffect(() => {
if (queryError && !fatalError) {
setFatalError(true);
console.error('Error from useQuery', queryError.message);
}
}, [queryError]);
useEffect(() => {
const info = document.getElementById('meow-common-phpinfo');
if (info) {
setPhpInfo(info.innerHTML);
}
}, []);
const handleUpdateOption = (value, id) => {
updateOptionMutation.mutate({
value,
id
});
};
const handleLoadErrorLogs = () => {
errorLogsMutation.mutate();
};
const jsxHideMeowApps = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSettings, {
title: "Main Menu"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "meowapps_hide_meowapps",
label: "Hide (Not Recommended)",
description: /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTypo, {
p: true
}, "This will hide the Meow Apps Menu (on the left side) and everything it contains. You can re-enable it through though an option that will be added in Settings \u2192 General."),
value: "1",
disabled: updateOptionMutation.isPending,
checked: hide_meowapps,
onChange: handleUpdateOption
})));
const jsxForceSSLVerify = /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_7__.NekoSettings, {
title: "SSL Verify"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_8__.NekoCheckboxGroup, {
max: "1"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_9__.NekoCheckbox, {
name: "force_sslverify",
label: "Force (Not Recommended)",
description: /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTypo, {
p: true
}, "This will enforce the usage of SSL when checking the license or updating the plugin."),
value: "1",
disabled: updateOptionMutation.isPending,
checked: force_sslverify,
onChange: handleUpdateOption
})));
return /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_10__.NekoPage, {
showRestError: fatalError
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_11__.NekoHeader, {
title: "The Dashboard"
}), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoColumn, {
full: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTabs, {
keepTabOnReload: true
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: "Meow Apps"
}, jsxTextStory, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoWrapper, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "AI Engine",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/ai-engine/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/ai-engine/",
rel: "noreferrer"
}, "AI Engine")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "This is the ultimate AI plugin for WordPress. From a chatbot adapted to your needs to an AI that can write your content for you, API, REST, and more."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/ai-engine/",
rel: "noreferrer"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://meowapps.com/ai-engine/",
rel: "noreferrer"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Media Cleaner",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/media-cleaner/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/media-cleaner/",
rel: "noreferrer"
}, "Media Cleaner")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Is your Media Library bloated, your database heavy, and your website running slow? Media Cleaner will clean your Media Library from the media entries (and files) which aren't used in your website, as well as broken entries."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/media-cleaner/",
rel: "noreferrer"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://meowapps.com/media-cleaner/",
rel: "noreferrer"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Database Cleaner",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/database-cleaner/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/database-cleaner/",
rel: "noreferrer"
}, "Database Cleaner")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Not only does Database Cleaner have a user-friendly UI, but it's also equipped to handle large DBs, giving it an edge over other plugins. It's a must-have for any WordPress site."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/database-cleaner/",
rel: "noreferrer"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://meowapps.com/database-cleaner/",
rel: "noreferrer"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Media File Renamer",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/media-file-renamer/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/media-file-renamer/",
rel: "noreferrer"
}, "Media File Renamer")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Rename and move files directly from the dashboard, manually, automatically or via AI, either individually or in bulk. It's the best way to rename your files."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/media-file-renamer/",
rel: "noreferrer"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://meowapps.com/media-file-renamer/",
rel: "noreferrer"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Social Engine",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/social-engine/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/social-engine/",
rel: "noreferrer"
}, "Social Engine")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Effortlessly schedule and automate the perfect posts for all your networks. Unlimited capabilities and infinite className=\"plugin-actual-desc\" extensibility, for free!"), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/social-engine/",
rel: "noreferrer"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://meowapps.com/social-engine/",
rel: "noreferrer"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Meow Analytics",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/meow-analytics/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/meow-analytics/"
}, "Meow Analytics")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Google Analytics for your website. Simple and fast."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/meow-analytics/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/meow-analytics/"
}, "Meow Apps")))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_12__.NekoColumn, {
minimal: true
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Contact Form Block",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/seo-engine/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
target: "_blank",
href: "https://wordpress.org/plugins/seo-engine/",
rel: "noreferrer"
}, "SEO Engine")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Optimize your content for SEO and for the AI world, with AI assistants... while keeping everything simple and fast, as it should be! \u270C\uFE0F"), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/seo-engine/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/seo-engine/"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Meow Gallery",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/meow-gallery/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/meow-gallery/"
}, "Meow Gallery")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Fast and beautiful galleries with many layouts. Forget the heavy and slow plugins, use the Meow Gallery for a better experience! \uD83D\uDC95"), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/meow-gallery/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/meow-gallery/"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Meow Lightbox",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/meow-lightbox/assets/icon-256x256.gif"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/meow-lightbox/"
}, "Meow Lightbox")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Sleek and performant lightbox with EXIF support."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/meow-lightbox/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/meow-lightbox/"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Perfect Images (Retina)",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/wp-retina-2x/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/wp-retina-2x/"
}, "Perfect Images")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Manage, Optimize, Replace your images with Perfect Images."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/wp-retina-2x/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/wp-retina-2x/"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Photo Engine",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/wplr-sync/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/wplr-sync/"
}, "Photo Engine")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Organize your photos in folders and collections. Synchronize with Lightroom. Simplify and speed up your workflow."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/wplr-sync/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/wplr-sync/"
}, "Meow Apps"))))), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginBlock, {
title: "Contact Form Block",
className: "primary"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPluginImage, {
src: "https://ps.w.org/contact-form-block/assets/icon-256x256.png"
}), /*#__PURE__*/React.createElement("div", {
className: "plugin-desc"
}, /*#__PURE__*/React.createElement("h2", null, /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/contact-form-block/"
}, "Contact Form Block")), /*#__PURE__*/React.createElement("p", {
className: "plugin-actual-desc"
}, "Need a very simple but straightforward contact form? This is the one you need. It's fast, simple, and efficient."), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("div", null, "Free Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://wordpress.org/plugins/contact-form-block/"
}, "WordPress.org")), /*#__PURE__*/React.createElement("div", null, "Pro Version: ", /*#__PURE__*/React.createElement("a", {
rel: "noreferrer",
target: "_blank",
href: "https://meowapps.com/contact-form-block/"
}, "Meow Apps")))))))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: "Performance"
}, jsxTextPerformance, /*#__PURE__*/React.createElement("div", {
style: {
display: 'flex',
justifyContent: 'space-around',
marginBottom: 25
}
}, /*#__PURE__*/React.createElement(_SpeedTester__WEBPACK_IMPORTED_MODULE_14__.SpeedTester, {
title: "Empty Request Time",
request: "empty_request",
max: 2500
}), /*#__PURE__*/React.createElement(_SpeedTester__WEBPACK_IMPORTED_MODULE_14__.SpeedTester, {
title: "File Operation Time",
request: "file_operation",
max: 2600
}), /*#__PURE__*/React.createElement(_SpeedTester__WEBPACK_IMPORTED_MODULE_14__.SpeedTester, {
title: "SQL Request Time",
request: "sql_request",
max: 2800
})), jsxTextRecommendations), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: "PHP Info"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPhpInfo, {
dangerouslySetInnerHTML: {
__html: phpInfo
}
})), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: "PHP Error Logs"
}, /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.TabText, null, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_15__.NekoButton, {
style: {
marginBottom: 10
},
color: '#ccb027',
onClick: handleLoadErrorLogs,
disabled: errorLogsMutation.isPending,
isBusy: errorLogsMutation.isPending
}, "Load PHP Error Logs"), /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_1__.StyledPhpErrorLogs, null, (errorLogsMutation.data || []).map(x => /*#__PURE__*/React.createElement("li", {
className: `log-${x.type}`,
key: x.id
}, /*#__PURE__*/React.createElement("span", {
className: "log-type"
}, x.type), /*#__PURE__*/React.createElement("span", {
className: "log-date"
}, x.date), /*#__PURE__*/React.createElement("span", {
className: "log-content"
}, x.content)))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_2__.NekoTypo, {
p: true
}, "If you don't see any errors, your host might not allow remote access to PHP error logs. Contact them for assistance, or look in your hosting control panel."))), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_13__.NekoTab, {
title: "Settings"
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_16__.NekoBlock, {
title: "Settings",
className: "primary"
}, jsxHideMeowApps, jsxForceSSLVerify))))));
};
/***/ }),
/***/ "./common/js/dashboard/Dashboard.styled.js":
/*!*************************************************!*\
!*** ./common/js/dashboard/Dashboard.styled.js ***!
\*************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ StyledPhpErrorLogs: () => (/* binding */ StyledPhpErrorLogs),
/* harmony export */ StyledPhpInfo: () => (/* binding */ StyledPhpInfo),
/* harmony export */ StyledPluginBlock: () => (/* binding */ StyledPluginBlock),
/* harmony export */ StyledPluginImage: () => (/* binding */ StyledPluginImage),
/* harmony export */ TabText: () => (/* binding */ TabText)
/* harmony export */ });
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "./node_modules/styled-components/dist/styled-components.browser.esm.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/layout/Block.js");
// React & Vendor Libs
// NekoUI
const TabText = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
color: white;
padding: 15px;
margin-bottom: -15px;
a {
color: #7dedff;
text-decoration: none;
}
p {
font-size: 15px;
}
`;
const StyledPluginBlock = (0,styled_components__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.NekoBlock))`
.neko-block-title {
display: none;
}
.plugin-desc {
display: flex;
flex-direction: column;
margin-left: 15px;
}
.neko-block-content {
display: flex;
padding: 15px;
h2 {
font-size: 18px;
margin: 0;
a {
text-decoration: none;
}
}
p {
margin: 0px;
margin-top: 10px;
font-size: 13px;
line-height: 1.5;
}
.plugin-actual-desc {
font-size: 13px;
font-weight: 500;
}
}
`;
const StyledPluginImage = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].img`
height: 125px;
width: auto;
border-radius: 10px;
background: lightgray;
`;
const StyledPhpInfo = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].div`
margin: 15px;
.center {
background: white;
color: black;
border-radius: 10px;
padding: 10px;
max-width: 100%
overflow: none;
h2 {
font-size: 26px;
}
table {
width: 100%;
tr td:first-child {
width: 220px;
font-weight: bold;
color: #1e7cba;
}
* {
overflow-wrap: anywhere;
}
}
}
hr {
border-color: #1e7cba;
}
`;
const StyledPhpErrorLogs = styled_components__WEBPACK_IMPORTED_MODULE_0__["default"].ul`
margin-top: 10px;
background: rgb(0, 72, 88);
padding: 10px;
color: rgb(58, 212, 58);
max-height: 600px;
min-height: 200px;
display: block;
font-family: monospace;
font-size: 12px;
white-space: pre;
overflow-x: auto;
width: calc(100vw - 276px);
color: white;
.log-date {
color: var(--neko-yellow);
margin-left: 8px;
}
.log-type {
background: #0000004d;
padding: 2px 5px;
border-radius: 8px;
text-transform: uppercase;
}
.log-content {
display: block;
}
.log-warning .log-type {
background: var(--neko-yellow);
color: white;
}
.log-fatal .log-type {
background: var(--neko-red);
color: white;
}
`;
/***/ }),
/***/ "./common/js/dashboard/SpeedTester.js":
/*!********************************************!*\
!*** ./common/js/dashboard/SpeedTester.js ***!
\********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ SpeedTester: () => (/* binding */ SpeedTester)
/* harmony export */ });
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Typography.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/misc/Gauge.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/button/Button.js");
/* harmony import */ var _neko_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @neko-ui */ "../neko-ui/src/helpers.js");
/* harmony import */ var _app_settings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @app/settings */ "./app/js/settings.js");
/* harmony import */ var _Dashboard_styled__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Dashboard.styled */ "./common/js/dashboard/Dashboard.styled.js");
// React & Vendor Libs
const {
useState,
useEffect
} = wp.element;
// NekoUI
// From Main Plugin
// Common
const CommonApiUrl = `${_app_settings__WEBPACK_IMPORTED_MODULE_0__.restUrl}/meow-common/v1`;
const SpeedTester = ({
request,
title,
max
}) => {
const [runRequests, setRunRequests] = useState(false);
const [results, setResults] = useState([]);
const resultsTotal = results.length > 0 ? results.reduce(function (a, b) {
return a + b;
}) : 0;
const resultsAverage = results.length > 0 ? Math.ceil(resultsTotal / results.length) : 0;
const isInitializing = !results.length && runRequests;
useEffect(() => {
if (!runRequests) {
return;
}
setTimeout(async () => {
const start = new Date().getTime();
await (0,_neko_ui__WEBPACK_IMPORTED_MODULE_1__.nekoFetch)(`${CommonApiUrl}/${request}`, {
method: 'POST',
nonce: _app_settings__WEBPACK_IMPORTED_MODULE_0__.restNonce
});
const end = new Date().getTime();
const time = end - start;
setResults(x => [...x, time]);
}, 1000);
}, [results]);
const toggleRequestsProcess = () => {
if (!runRequests) {
setResults([]);
}
setRunRequests(!runRequests);
};
return /*#__PURE__*/React.createElement(_Dashboard_styled__WEBPACK_IMPORTED_MODULE_2__.TabText, {
style: {
width: 200,
textAlign: 'center'
}
}, /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_3__.NekoTypo, {
h2: true,
style: {
color: 'white'
}
}, title), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_4__.NekoGauge, {
size: 200,
value: isInitializing ? max : resultsAverage,
max: max
}, /*#__PURE__*/React.createElement("span", {
style: {
fontSize: 20
}
}, isInitializing ? 'START' : resultsAverage + ' ms'), /*#__PURE__*/React.createElement("span", {
style: {
fontSize: 12
}
}, isInitializing ? 'YOUR ENGINE' : results.length + ' requests')), /*#__PURE__*/React.createElement(_neko_ui__WEBPACK_IMPORTED_MODULE_5__.NekoButton, {
style: {
width: '100%',
marginTop: 10
},
color: runRequests ? '#cc3627' : '#ccb027',
onClick: toggleRequestsProcess
}, runRequests ? 'Stop' : 'Start'));
};
/***/ }),
/***/ "react":
/*!************************!*\
!*** external "React" ***!
\************************/
/***/ ((module) => {
module.exports = React;
/***/ }),
/***/ "react-dom":
/*!***************************!*\
!*** external "ReactDOM" ***!
\***************************/
/***/ ((module) => {
module.exports = ReactDOM;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/chunk loaded */
/******/ (() => {
/******/ var deferred = [];
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
/******/ if(chunkIds) {
/******/ priority = priority || 0;
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
/******/ deferred[i] = [chunkIds, fn, priority];
/******/ return;
/******/ }
/******/ var notFulfilled = Infinity;
/******/ for (var i = 0; i < deferred.length; i++) {
/******/ var [chunkIds, fn, priority] = deferred[i];
/******/ var fulfilled = true;
/******/ for (var j = 0; j < chunkIds.length; j++) {
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
/******/ chunkIds.splice(j--, 1);
/******/ } else {
/******/ fulfilled = false;
/******/ if(priority < notFulfilled) notFulfilled = priority;
/******/ }
/******/ }
/******/ if(fulfilled) {
/******/ deferred.splice(i--, 1)
/******/ var r = fn();
/******/ if (r !== undefined) result = r;
/******/ }
/******/ }
/******/ return result;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/global */
/******/ (() => {
/******/ __webpack_require__.g = (function() {
/******/ if (typeof globalThis === 'object') return globalThis;
/******/ try {
/******/ return this || new Function('return this')();
/******/ } catch (e) {
/******/ if (typeof window === 'object') return window;
/******/ }
/******/ })();
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/load script */
/******/ (() => {
/******/ var inProgress = {};
/******/ var dataWebpackPrefix = "ai-engine:";
/******/ // loadScript function to load a script via script tag
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
/******/ var script, needAttach;
/******/ if(key !== undefined) {
/******/ var scripts = document.getElementsByTagName("script");
/******/ for(var i = 0; i < scripts.length; i++) {
/******/ var s = scripts[i];
/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
/******/ }
/******/ }
/******/ if(!script) {
/******/ needAttach = true;
/******/ script = document.createElement('script');
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
/******/
/******/ script.src = url;
/******/ }
/******/ inProgress[url] = [done];
/******/ var onScriptComplete = (prev, event) => {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var doneFns = inProgress[url];
/******/ delete inProgress[url];
/******/ script.parentNode && script.parentNode.removeChild(script);
/******/ doneFns && doneFns.forEach((fn) => (fn(event)));
/******/ if(prev) return prev(event);
/******/ }
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
/******/ script.onload = onScriptComplete.bind(null, script.onload);
/******/ needAttach && document.head.appendChild(script);
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ var scriptUrl;
/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
/******/ var document = __webpack_require__.g.document;
/******/ if (!scriptUrl && document) {
/******/ if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')
/******/ scriptUrl = document.currentScript.src;
/******/ if (!scriptUrl) {
/******/ var scripts = document.getElementsByTagName("script");
/******/ if(scripts.length) {
/******/ var i = scripts.length - 1;
/******/ while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;
/******/ }
/******/ }
/******/ }
/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
/******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
/******/ __webpack_require__.p = scriptUrl;
/******/ })();
/******/
/******/ /* webpack/runtime/jsonp chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ "index": 0
/******/ };
/******/
/******/ __webpack_require__.f.j = (chunkId, promises) => {
/******/ // JSONP chunk loading for javascript
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ if(true) { // all chunks have JS
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ var loadingEnded = (event) => {
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
/******/ installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
/******/ if(installedChunkData) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ installedChunkData[1](error);
/******/ }
/******/ }
/******/ };
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
/******/ }
/******/ }
/******/ }
/******/ };
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/
/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
/******/
/******/ // install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ return __webpack_require__.O(result);
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["wpJsonMwai"] = self["wpJsonMwai"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ })();
/******/
/******/ /* webpack/runtime/nonce */
/******/ (() => {
/******/ __webpack_require__.nc = undefined;
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["vendor"], () => (__webpack_require__("./app/js/index.js")))
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
/******/
/******/ })()
;
//# sourceMappingURL=index.js.map