@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
320 lines (258 loc) • 11.6 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.core.js');
require('./kendo.data.js');
require('./kendo.icons.js');
require('./kendo.textarea.js');
require('./kendo.button.js');
require('./kendo.toolbar.js');
require('./kendo.popup.js');
require('./kendo.licensing.js');
require('@progress/kendo-licensing');
require('./kendo.data.odata.js');
require('./kendo.data.xml.js');
require('./kendo.html.icon.js');
require('./kendo.html.base.js');
require('@progress/kendo-svg-icons');
require('./kendo.floatinglabel.js');
require('./prefix-suffix-containers-BmDm564f.js');
require('./kendo.badge.js');
require('./kendo.html.button.js');
require('./kendo.splitbutton.js');
require('./kendo.button.menu.js');
require('./kendo.dropdownbutton.js');
require('./kendo.buttongroup.js');
require('./kendo.togglebutton.js');
require('./kendo.menu.js');
const __meta__ = {
id: "inlineaiprompt",
name: "InlineAIPrompt",
category: "web",
description: "The InlineAIPrompt component simplifies the incorporation of external AI services into apps.",
depends: ["core", "icons", "textarea", "button", "toolbar", "popup", "data"],
};
(function($) {
let kendo = window.kendo,
Widget = kendo.ui.Widget,
NS = ".kendoInlineAIPrompt",
ui = kendo.ui,
PROMPT_REQUEST = "promptRequest",
PROMPT_RESPONSE = "promptResponse",
PROMPT_ACTION = "promptAction",
FOCUS = "focus";
let InlineAIPrompt = Widget.extend({
init: function(element, options) {
let that = this;
options = options || {};
that.options.systemPrompt = options.systemPrompt || that.options.systemPrompt;
Widget.fn.init.call(that, element, options);
if (options.commands) {
that.options.commands = options.commands;
}
that.transport = new kendo.data.AiTransport({
service: that.options.service,
success: that._serviceSuccess.bind(that),
requestStart: () => kendo.ui.progress(that._popup.element, true)
});
that._initPopup();
that._initContextMenu();
that._bindEvents();
kendo.notify(that);
},
options: {
name: "InlineAIPrompt",
systemPrompt: (context, prompt) => `You are an advanced AI language assistant.
A user has selected a portion of their text and provided a query regarding how they want it modified.
Your task is to accurately respond to their request while preserving the original intent of the text.
Follow the instructions strictly and provide only the requested output unless explicitly asked to explain your changes.
Selected Text:
${context}
User's Request:
${prompt}
Response:`,
commands: []
},
events: [
PROMPT_REQUEST,
PROMPT_RESPONSE,
PROMPT_ACTION
],
open: function(x, y) {
let that = this;
that._popup.open(x, y);
},
_serviceSuccess: function(output) {
const that = this;
that._popup.element.find('.k-card-body').html(output.output);
that._popup.element.find('.k-card').show();
that.trigger(PROMPT_RESPONSE, { output });
kendo.ui.progress(that._popup.element, false);
},
_initPopup: function() {
const that = this,
html = $(that._template()).width(that.options.width);
html.css({ "max-width": "98vw" });
that._popup = new kendo.ui.Popup(html, {
anchor: that.element,
animation: {
open: {
effects: "zoom:in",
duration: 200
},
close: {
effects: "zoom:out",
duration: 200
}
},
open: function() {
this.element.find('.k-card').hide();
this.element.find('.k-card-body').empty();
this.element.find('.k-input-inner').val('');
},
close: function() {
kendo.ui.progress(that._popup.element, false);
that._aiContextMenu?.close();
}
});
},
_template: function() {
const template = `<div class="k-child-animation-container">
<div class="k-prompt-popup k-popup">
<div class="k-prompt">
<div class="k-prompt-content">
<div class="k-prompt-view">
<div class="k-card">
<div class="k-card-body" style="max-height: 150px; overflow-y: auto;"></div>
<div class="k-actions k-actions-start k-actions-horizontal k-card-actions">
${kendo.html.renderButton(`<button ${kendo.attr("action")}='insert'>Insert</button>`, { icon: "insert-bottom", fillMode: "flat" })}
${kendo.html.renderButton(`<button ${kendo.attr("action")}='replace'>Replace</button>`, { icon: "check", fillMode: "flat" })}
${kendo.html.renderButton(`<button ${kendo.attr("action")}='cancel'>Discard</button>`, { icon: "cancel-outline", fillMode: "flat" })}
</div>
</div>
<span class="k-textbox k-input k-input-md k-input-solid k-rounded-md">
<span class="k-input-prefix k-input-prefix-horizontal">
${kendo.html.renderButton(`<button></button>`, { icon: "sparkles", fillMode: "flat" })}
</span>
<input type="text" class="k-input-inner" placeholder="Edit, generate or explain ..." autocomplete="off" value="">
<span class="k-input-suffix k-input-suffix-horizontal">
${kendo.html.renderButton(`<button></button>`, { icon: "paper-plane", fillMode: "flat" })}
</span>
</span>
</div>
</div>
</div>
</div>
</div>`;
return template;
},
_initContextMenu: function() {
const that = this;
if (!that.options.commands || that.options.commands?.length === 0) {
that._popup.element.find('.k-input-prefix button').addClass('k-disabled');
return;
}
const itemsHtml = that.options.commands.map(command => that._createCommandHtml(command)).join('');
const html = $(`<ul>
${itemsHtml}
</ul>`);
$('body').append(html);
that._aiContextMenu = html.kendoContextMenu({
target: that._popup.element,
anchor: that._popup.element,
showOn: 'click',
appendTo: $(document.body),
filter: '.invalid',
select: that._executeCommand.bind(that),
close: () => {
that._popup.element.find('.k-input-inner').focus();
}
}).data('kendoContextMenu');
},
_createCommandHtml: function(command) {
const that = this;
const icon = kendo.html.renderIcon({ icon: command.icon });
const text = command.text;
const items = command.items || [];
const itemsHtml = items.map(item => that._createCommandHtml(item)).join('');
return `<li ${kendo.attr("name")}=${command.id}>${icon} ${text}${itemsHtml ? "<ul>" + itemsHtml + "</ul>" : ""}</li>`;
},
_executeCommand: function(e) {
const that = this;
const command = that._findCommand(that.options.commands, e.item.getAttribute(kendo.attr("name")));
const data = {
query: command.id,
selection: ""
};
that.trigger(PROMPT_REQUEST, data);
const selection = data.selection || data.context;
const prompt = command.prompt(selection);
that._aiContextMenu?.close();
that.transport.read({ prompt, history: [], isRetry: false });
},
_findCommand: function(commands, id) {
const that = this;
for (const command of commands) {
if (command.id === id) {
return command;
}
if (command.items) {
const found = that._findCommand(command.items, id);
if (found) {
return found;
}
}
}
},
_bindEvents: function() {
const that = this;
that._popup.element.find('.k-input-prefix button').on('click', function() {
that._aiContextMenu?.open();
});
that._popup.element.find('.k-input-suffix button').on('click', function() {
const prompt = that._popup.element.find('.k-input-inner').val();
that._requestService(prompt);
});
that._popup.element.find('.k-input-inner').on('keypress', function(e) {
if (e.keyCode === 13) {
const prompt = $(e.currentTarget).val();
that._requestService(prompt);
}
});
that._popup.element.find('.k-card-actions button').on('click', function(e) {
const action = $(e.currentTarget).attr(kendo.attr("action"));
const content = that._popup.element.find('.k-card-body').text();
that.trigger(PROMPT_ACTION, { action, content });
that._popup.close();
});
},
_requestService: function(query) {
const that = this;
const data = {
query,
context: ""
};
if (!query.trim()) {
return;
}
that.trigger(PROMPT_REQUEST, data);
const context = data.context;
const prompt = that.options.systemPrompt(context, query);
that.transport.read({ prompt, history: [], isRetry: false });
},
focus: function() {
let that = this;
that.element.trigger(FOCUS);
},
destroy: function() {
let that = this;
that.toolbar?.destroy();
that._selectedView?.destroy();
that.element.off(NS);
Widget.fn.destroy.call(that);
}
});
ui.plugin(InlineAIPrompt);
})(window.kendo.jQuery);
var kendo$1 = kendo;
exports.__meta__ = __meta__;
exports.default = kendo$1;