ai-text-processor
Advanced tools
Comparing version 1.0.11 to 1.0.12
@@ -33,3 +33,3 @@ "use strict"; | ||
const AITextProcessor = (_a) => { | ||
var _b, _c, _d, _e, _f, _g, _h; | ||
var _b, _c, _d, _e, _f, _g, _h, _j, _k; | ||
var props = __rest(_a, []); | ||
@@ -40,2 +40,3 @@ const localSettings = (0, useLocalSettings_1.useLocalSettings)(); | ||
const [presetName, setPresetName] = localSettings[useLocalSettings_1.LocalSettingsKeys.presetName]; | ||
const [presetDescription, setPresetDescription] = localSettings[useLocalSettings_1.LocalSettingsKeys.presetDescription]; | ||
const [openAiModel, setOpenAiModel] = localSettings[useLocalSettings_1.LocalSettingsKeys.openAiModel]; | ||
@@ -70,6 +71,9 @@ const [systemPrompt, setSystemPrompt] = localSettings[useLocalSettings_1.LocalSettingsKeys.systemPrompt]; | ||
const retryingRef = react_1.default.useRef(false); | ||
const [showDeletePresetConfirmation, setShowDeletePresetConfirmation] = react_1.default.useState(false); | ||
const [variableDeletionConfirmationIndex, setVariableDeletionConfirmationIndex] = react_1.default.useState(-1); | ||
const [showDeleteOutputConfirmation, setShowDeleteOutputConfirmation] = react_1.default.useState(false); | ||
let preparedUserPrompt = userPrompt !== null && userPrompt !== void 0 ? userPrompt : ''; | ||
variables.forEach((variable) => { | ||
var _a; | ||
const replacement = (_a = variableValues[variable]) !== null && _a !== void 0 ? _a : ''; | ||
const replacement = (_a = (variableValues !== null && variableValues !== void 0 ? variableValues : {})[variable]) !== null && _a !== void 0 ? _a : ''; | ||
preparedUserPrompt = preparedUserPrompt.split(variable).join(replacement); | ||
@@ -163,2 +167,6 @@ }); | ||
}; | ||
const handleSetUserPrompt = (text) => { | ||
setUserPrompt(text); | ||
setVariableDeletionConfirmationIndex(-1); | ||
}; | ||
const handleSetInput = (text) => { | ||
@@ -198,2 +206,3 @@ if (autoShrinkEnabled) { | ||
setPresetName(useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.presetName]); | ||
setPresetDescription(useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.presetDescription]); | ||
setOpenAiModel(useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.openAiModel]); | ||
@@ -211,19 +220,20 @@ setSystemPrompt(useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.systemPrompt]); | ||
else { | ||
const selectedPreset = (mergedPresets !== null && mergedPresets !== void 0 ? mergedPresets : {})[presetName]; | ||
if (selectedPreset) { | ||
const chosenPreset = (mergedPresets !== null && mergedPresets !== void 0 ? mergedPresets : {})[presetName]; | ||
if (chosenPreset) { | ||
setSelectedPresetName(presetName); | ||
setPresetName((_a = selectedPreset.name) !== null && _a !== void 0 ? _a : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.presetName]); | ||
setOpenAiModel((_b = selectedPreset.aiModel) !== null && _b !== void 0 ? _b : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.openAiModel]); | ||
setSystemPrompt((_c = selectedPreset.systemPrompt) !== null && _c !== void 0 ? _c : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.systemPrompt]); | ||
setUserPrompt((_d = selectedPreset.userPrompt) !== null && _d !== void 0 ? _d : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.userPrompt]); | ||
setAverageTokenLength((_e = selectedPreset.averageTokenLength) !== null && _e !== void 0 ? _e : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.averageTokenLength]); | ||
setRequestMaxTokenRatio((_f = selectedPreset.requestMaxTokenRatio) !== null && _f !== void 0 ? _f : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.requestMaxTokenRatio]); | ||
setChunkOverlapWordCount((_g = selectedPreset.chunkOverlapWordCount) !== null && _g !== void 0 ? _g : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.chunkOverlapWordCount]); | ||
setChunkPrefix((_h = selectedPreset.chunkPrefix) !== null && _h !== void 0 ? _h : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.chunkPrefix]); | ||
setAutoShrinkEnabled((_j = selectedPreset.autoShrink) !== null && _j !== void 0 ? _j : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.chunkPrefix]); | ||
setVariableValues((_k = selectedPreset.variableValues) !== null && _k !== void 0 ? _k : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.variableValues]); | ||
setVariableOptions((_l = selectedPreset.variableOptions) !== null && _l !== void 0 ? _l : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.variableOptions]); | ||
(_m = inputTextFieldRef.current) === null || _m === void 0 ? void 0 : _m.select(); | ||
setPresetName((_a = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.name) !== null && _a !== void 0 ? _a : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.presetName]); | ||
setPresetDescription((_b = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.description) !== null && _b !== void 0 ? _b : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.presetDescription]); | ||
setOpenAiModel((_c = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.aiModel) !== null && _c !== void 0 ? _c : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.openAiModel]); | ||
setSystemPrompt((_d = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.systemPrompt) !== null && _d !== void 0 ? _d : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.systemPrompt]); | ||
setUserPrompt((_e = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.userPrompt) !== null && _e !== void 0 ? _e : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.userPrompt]); | ||
setAverageTokenLength((_f = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.averageTokenLength) !== null && _f !== void 0 ? _f : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.averageTokenLength]); | ||
setRequestMaxTokenRatio((_g = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.requestMaxTokenRatio) !== null && _g !== void 0 ? _g : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.requestMaxTokenRatio]); | ||
setChunkOverlapWordCount((_h = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.chunkOverlapWordCount) !== null && _h !== void 0 ? _h : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.chunkOverlapWordCount]); | ||
setChunkPrefix((_j = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.chunkPrefix) !== null && _j !== void 0 ? _j : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.chunkPrefix]); | ||
setAutoShrinkEnabled((_k = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.autoShrink) !== null && _k !== void 0 ? _k : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.chunkPrefix]); | ||
setVariableValues((_l = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.variableValues) !== null && _l !== void 0 ? _l : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.variableValues]); | ||
setVariableOptions((_m = chosenPreset === null || chosenPreset === void 0 ? void 0 : chosenPreset.variableOptions) !== null && _m !== void 0 ? _m : useLocalSettings_1.LocalSettingsDefaults[useLocalSettings_1.LocalSettingsKeys.variableOptions]); | ||
} | ||
} | ||
setVariableDeletionConfirmationIndex(-1); | ||
}; | ||
@@ -233,2 +243,3 @@ const handleSavePreset = () => { | ||
name: presetName, | ||
description: presetDescription, | ||
aiModel: openAiModel, | ||
@@ -252,2 +263,5 @@ systemPrompt: systemPrompt, | ||
const handleDeletePreset = () => { | ||
setShowDeletePresetConfirmation(true); | ||
}; | ||
const handleConfirmDeletePreset = () => { | ||
if (selectedPresetName) { | ||
@@ -259,3 +273,10 @@ const newPresets = Object.assign({}, (mergedPresets !== null && mergedPresets !== void 0 ? mergedPresets : {})); | ||
handleSelectPreset(''); | ||
setShowDeletePresetConfirmation(false); | ||
}; | ||
const handleCancelDeletePreset = () => { | ||
setShowDeletePresetConfirmation(false); | ||
}; | ||
const handleResetPreset = () => { | ||
handleSelectPreset(selectedPresetName); | ||
}; | ||
const handleCopy = () => { | ||
@@ -265,3 +286,6 @@ (0, copy_to_clipboard_1.default)((outputs !== null && outputs !== void 0 ? outputs : []).join('\n\n')); | ||
}; | ||
const handleClear = () => { | ||
const handleDeleteOutput = () => { | ||
setShowDeleteOutputConfirmation(true); | ||
}; | ||
const handleConfirmDeleteOutput = () => { | ||
setOutputs([]); | ||
@@ -274,3 +298,7 @@ outputsRef.current = []; | ||
setXhr(undefined); | ||
setShowDeleteOutputConfirmation(false); | ||
}; | ||
const handleCancelDeleteOutput = () => { | ||
setShowDeleteOutputConfirmation(false); | ||
}; | ||
const handleInputTextFieldFocus = () => { | ||
@@ -307,3 +335,3 @@ var _a; | ||
return (react_1.default.createElement(react_bootstrap_1.Alert, { key: `chunk-${i}`, variant: "secondary" }, | ||
react_1.default.createElement("div", { className: "d-flex align-items-center justify-content-between gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center justify-content-between gap-2" }, | ||
react_1.default.createElement("h6", { className: "mb-0" }, | ||
@@ -324,3 +352,5 @@ react_1.default.createElement(react_bootstrap_1.Badge, { bg: "secondary" }, | ||
return (react_1.default.createElement(react_bootstrap_1.Alert, { key: `output-${i}`, variant: "light", className: "text-black mb-0" }, | ||
react_1.default.createElement(Markdown_1.Markdown, null, output))); | ||
react_1.default.createElement(Markdown_1.Markdown, null, | ||
output, | ||
output && processingRef.current ? '│' : ''))); | ||
}); | ||
@@ -339,3 +369,6 @@ const handleSetVariableValue = (variable, value) => { | ||
}; | ||
const handleDeleteVariableOption = (variable, option) => { | ||
const handleDeleteVariableOption = (variableIndex) => { | ||
setVariableDeletionConfirmationIndex(variableIndex); | ||
}; | ||
const handleConfirmDeleteVariableOption = (variable, option) => { | ||
const newVariableOptions = Object.assign({}, variableOptions); | ||
@@ -349,3 +382,7 @@ const newOptions = Array.isArray(newVariableOptions[variable]) ? newVariableOptions[variable] : []; | ||
handleSetVariableValue(variable, ''); | ||
setVariableDeletionConfirmationIndex(-1); | ||
}; | ||
const handleCancelDeleteVariableOption = () => { | ||
setVariableDeletionConfirmationIndex(-1); | ||
}; | ||
const variableElements = variables.map((variable, i) => { | ||
@@ -359,31 +396,44 @@ var _a; | ||
const currVarOpts = Array.isArray(variableOptions[variable]) ? variableOptions[variable] : []; | ||
const currValueOptionElements = currVarOpts.map((varValue, j) => (react_1.default.createElement("option", { key: `var-${i}-opt-${j}`, value: varValue }, varValue))); | ||
const currValueDropdownItemElements = currVarOpts.map((varValue, j) => (react_1.default.createElement(react_bootstrap_1.Dropdown.Item, { key: `var-${i}-dropdown-item-${j}`, onClick: () => handleSetVariableValue(variable, varValue) }, varValue))); | ||
const canAddVariableOption = !!currVarValue && !currVarOpts.includes(currVarValue); | ||
const canDeleteVariableOption = !!currVarValue; | ||
return (react_1.default.createElement("div", { key: `variable-${i}`, className: "d-flex gap-1 mb-1" }, | ||
return (react_1.default.createElement("div", { key: `variable-${i}`, className: "d-flex flex-wrap gap-1 mb-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { size: "sm", type: "text", disabled: true, value: currVarName, style: { width: 150 } }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", size: "sm", placeholder: "Value", value: currVarValue, onChange: (e) => handleSetVariableValue(variable, e.target.value), style: { width: 150 } }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Select, { size: "sm", value: currVarValue, onChange: (e) => handleSetVariableValue(variable, e.target.value), style: { width: 20 } }, | ||
react_1.default.createElement("option", { value: "" }), | ||
currValueOptionElements), | ||
react_1.default.createElement(react_bootstrap_1.Dropdown, { as: react_bootstrap_1.ButtonGroup }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", size: "sm", placeholder: "Value", value: currVarValue, onChange: (e) => handleSetVariableValue(variable, e.target.value), style: { width: 150, borderTopRightRadius: 0, borderBottomRightRadius: 0 } }), | ||
react_1.default.createElement(react_bootstrap_1.Dropdown.Toggle, { split: true, variant: "secondary", id: `variable-dropdown-${currVarName}` }), | ||
react_1.default.createElement(react_bootstrap_1.Dropdown.Menu, null, currValueDropdownItemElements)), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-primary", size: "sm", onClick: () => handleAddVariableOption(variable, currVarValue), disabled: !canAddVariableOption }, | ||
react_1.default.createElement(fa_1.FaPlus, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", size: "sm", onClick: () => handleDeleteVariableOption(variable, currVarValue), disabled: !canDeleteVariableOption }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, { className: "mb-1" })))); | ||
i !== variableDeletionConfirmationIndex && (react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", size: "sm", onClick: () => handleDeleteVariableOption(i), disabled: !canDeleteVariableOption }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, { className: "mb-1" }))), | ||
i === variableDeletionConfirmationIndex && (react_1.default.createElement("div", { className: "d-flex align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { size: "sm", variant: "outline-danger", onClick: (e) => { | ||
handleConfirmDeleteVariableOption(variable, currVarValue); | ||
} }, | ||
react_1.default.createElement(fa_1.FaCheck, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { size: "sm", variant: "outline-secondary", onClick: (e) => { | ||
handleCancelDeleteVariableOption(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaTimes, { className: "mb-1" })))))); | ||
}); | ||
const showProcessingAlert = processingRef.current && ((outputs !== null && outputs !== void 0 ? outputs : []).length < currentChunkIndex + 1 || retryingRef.current); | ||
const selectedPreset = (mergedPresets !== null && mergedPresets !== void 0 ? mergedPresets : {})[selectedPresetName]; | ||
const hasChanges = !selectedPreset || | ||
(selectedPreset && selectedPreset.name !== presetName) || | ||
selectedPreset.aiModel !== openAiModel || | ||
selectedPreset.systemPrompt !== systemPrompt || | ||
selectedPreset.userPrompt !== userPrompt || | ||
selectedPreset.averageTokenLength !== averageTokenLength || | ||
selectedPreset.requestMaxTokenRatio !== requestMaxTokenRatio || | ||
selectedPreset.chunkOverlapWordCount !== chunkOverlapWordCount || | ||
selectedPreset.chunkPrefix !== chunkPrefix || | ||
!!selectedPreset.autoShrink !== !!autoShrinkEnabled || | ||
JSON.stringify(selectedPreset.variableValues) !== JSON.stringify(variableValues !== null && variableValues !== void 0 ? variableValues : {}) || | ||
JSON.stringify(selectedPreset.variableOptions) !== JSON.stringify(variableOptions !== null && variableOptions !== void 0 ? variableOptions : {}); | ||
const canSave = !!presetName.trim() && hasChanges; | ||
/** Has changes the user will be interested in saving. */ | ||
const hasMeaningfulChanges = !selectedPreset || | ||
(selectedPreset && (selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.name) !== presetName) || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.aiModel) !== openAiModel || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.systemPrompt) !== systemPrompt || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.userPrompt) !== userPrompt || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.averageTokenLength) !== averageTokenLength || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.requestMaxTokenRatio) !== requestMaxTokenRatio || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.chunkOverlapWordCount) !== chunkOverlapWordCount || | ||
(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.chunkPrefix) !== chunkPrefix || | ||
!!(selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.autoShrink) !== !!autoShrinkEnabled || | ||
JSON.stringify((_d = selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.variableOptions) !== null && _d !== void 0 ? _d : {}) !== JSON.stringify(variableOptions !== null && variableOptions !== void 0 ? variableOptions : {}); | ||
/** Has changes the user might not necessarily be interested in saving. */ | ||
const hasSuperfluousChanges = JSON.stringify((_e = selectedPreset === null || selectedPreset === void 0 ? void 0 : selectedPreset.variableValues) !== null && _e !== void 0 ? _e : {}) !== JSON.stringify(variableValues !== null && variableValues !== void 0 ? variableValues : {}); | ||
const showUnsavedNotification = !!presetName.trim() && hasMeaningfulChanges; | ||
const canSave = !!presetName.trim() && (hasMeaningfulChanges || hasSuperfluousChanges); | ||
const canReset = !!selectedPreset && canSave; | ||
const configured = !!openAiModel && !!userPrompt; | ||
@@ -408,9 +458,47 @@ const canExecute = configured && !!input; | ||
react_1.default.createElement(react_bootstrap_1.Form.Text, { className: "text-muted" }, "Select a preset, or choose New Preset to create a new one. Note that default presets cannot be deleted.")), | ||
presetDescription && (react_1.default.createElement(react_bootstrap_1.Alert, { variant: "info", className: "mb-0 py-1" }, | ||
react_1.default.createElement("div", { className: "d-flex gap-2" }, | ||
react_1.default.createElement(fa_1.FaInfoCircle, { className: "mt-1" }), | ||
" ", | ||
presetDescription))), | ||
react_1.default.createElement(react_bootstrap_1.Accordion, { key: `accordion-${!selectedPresetName ? 'new' : 'saved'}`, defaultActiveKey: !selectedPresetName ? '1' : undefined }, | ||
react_1.default.createElement(react_bootstrap_1.Accordion.Item, { eventKey: "1" }, | ||
react_1.default.createElement(react_bootstrap_1.Accordion.Header, null, | ||
react_1.default.createElement("div", { className: "d-flex align-items-center gap-2" }, | ||
!configured ? react_1.default.createElement(fa_1.FaWrench, null) : react_1.default.createElement(fa_1.FaCheckSquare, { className: "text-success" }), | ||
" Preset Configuration", | ||
canSave && react_1.default.createElement(react_bootstrap_1.Badge, { bg: "primary" }, "Unsaved"))), | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap justify-content-between gap-2 w-100 me-4" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center gap-2" }, | ||
!configured ? react_1.default.createElement(fa_1.FaWrench, null) : react_1.default.createElement(fa_1.FaCheckSquare, { className: "text-success" }), | ||
" Preset Configuration", | ||
showUnsavedNotification && react_1.default.createElement(react_bootstrap_1.Badge, { bg: "primary" }, "Unsaved")), | ||
react_1.default.createElement("div", { className: "d-flex justify-content-end gap-2", onClick: (e) => e.stopPropagation() }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-primary", size: "sm", onClick: (e) => { | ||
handleSavePreset(); | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
}, disabled: !canSave }, | ||
react_1.default.createElement(fa_1.FaSave, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-secondary", size: "sm", onClick: (e) => { | ||
handleResetPreset(); | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
}, disabled: !canReset }, | ||
react_1.default.createElement(fa_1.FaUndo, { className: "mb-1" })), | ||
!showDeletePresetConfirmation && (react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", size: "sm", onClick: (e) => { | ||
handleDeletePreset(); | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, { className: "mb-1" }))), | ||
showDeletePresetConfirmation && (react_1.default.createElement("div", { className: "d-flex align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", size: "sm", onClick: (e) => { | ||
handleConfirmDeletePreset(); | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaCheck, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-secondary", size: "sm", onClick: (e) => { | ||
handleCancelDeletePreset(); | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaTimes, { className: "mb-1" }))))))), | ||
react_1.default.createElement(react_bootstrap_1.Accordion.Body, { className: "d-flex flex-column gap-2" }, | ||
@@ -421,2 +509,6 @@ react_1.default.createElement(react_bootstrap_1.Form.Group, { controlId: "name-group" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Text, { className: "text-muted" }, "Provide a name for this preset.")), | ||
react_1.default.createElement(react_bootstrap_1.Form.Group, { controlId: "name-group" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Label, { className: "small fw-bold mb-1" }, "Description"), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Enter a description", value: presetDescription, onChange: (e) => setPresetDescription(e.target.value) }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Text, { className: "text-muted" }, "Provide an optional description for this preset.")), | ||
react_1.default.createElement(react_bootstrap_1.Form.Group, { controlId: "model-group" }, | ||
@@ -438,3 +530,3 @@ react_1.default.createElement(react_bootstrap_1.Form.Label, { className: "small fw-bold mb-1" }, "AI Model"), | ||
react_1.default.createElement(react_bootstrap_1.Form.Label, { className: "small fw-bold mb-1" }, "User Prompt"), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { as: "textarea", placeholder: "Enter the user prompt", rows: 3, value: userPrompt, onChange: (e) => setUserPrompt(e.target.value) }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { as: "textarea", placeholder: "Enter the user prompt", rows: 3, value: userPrompt, onChange: (e) => handleSetUserPrompt(e.target.value) }), | ||
react_1.default.createElement("div", { className: "d-flex justify-content-between gap-2" }, | ||
@@ -470,10 +562,10 @@ react_1.default.createElement(react_bootstrap_1.Form.Text, { className: "text-muted" }, | ||
"), and the max tokens for the model is", | ||
' ', (_d = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _d !== void 0 ? _d : 4000, | ||
' ', (_f = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _f !== void 0 ? _f : 4000, | ||
", each request (chunk) will have", | ||
' ', | ||
Math.ceil(((_e = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _e !== void 0 ? _e : 4000) * requestMaxTokenRatio), | ||
Math.ceil(((_g = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _g !== void 0 ? _g : 4000) * requestMaxTokenRatio), | ||
" tokens max. This would leave about", | ||
' ', | ||
((_f = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _f !== void 0 ? _f : 4000) - | ||
Math.ceil(((_g = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _g !== void 0 ? _g : 4000) * requestMaxTokenRatio), | ||
((_h = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _h !== void 0 ? _h : 4000) - | ||
Math.ceil(((_j = currentOpenAiModelInfo === null || currentOpenAiModelInfo === void 0 ? void 0 : currentOpenAiModelInfo.maxTokens) !== null && _j !== void 0 ? _j : 4000) * requestMaxTokenRatio), | ||
' ', | ||
@@ -495,4 +587,17 @@ "tokens for a meaningful response, per request. For each chunk, we want to make sure there is still a decent amount of tokens left for the response.")), | ||
react_1.default.createElement(fa_1.FaSave, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", onClick: handleDeletePreset }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, { className: "mb-1" })))))), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-secondary", onClick: handleResetPreset, disabled: !canReset }, | ||
react_1.default.createElement(fa_1.FaUndo, { className: "mb-1" })), | ||
!showDeletePresetConfirmation && (react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", onClick: (e) => { | ||
handleDeletePreset(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, { className: "mb-1" }))), | ||
showDeletePresetConfirmation && (react_1.default.createElement("div", { className: "d-flex align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", onClick: (e) => { | ||
handleConfirmDeletePreset(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaCheck, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-secondary", onClick: (e) => { | ||
handleCancelDeletePreset(); | ||
} }, | ||
react_1.default.createElement(fa_1.FaTimes, { className: "mb-1" })))))))), | ||
variableElements.length > 0 && (react_1.default.createElement(react_bootstrap_1.Form.Group, { controlId: "variables-group" }, | ||
@@ -506,4 +611,4 @@ react_1.default.createElement(react_bootstrap_1.Form.Label, { className: "small fw-bold mb-1" }, "Variables:"), | ||
}, onFocus: handleInputTextFieldFocus })), | ||
react_1.default.createElement("div", { className: "d-flex justify-content-between align-items-start gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex align-items-center gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap justify-content-between align-items-start gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center gap-2" }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-primary", size: "sm", onClick: handlePaste }, "Paste"), | ||
@@ -541,4 +646,4 @@ react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", size: "sm", onClick: handleClearInput, disabled: !hasInput }, "Clear"), | ||
react_1.default.createElement(react_bootstrap_1.Card, null, | ||
react_1.default.createElement(react_bootstrap_1.Card.Header, { className: "d-flex justify-content-between align-items-center gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex align-items-center gap-2" }, | ||
react_1.default.createElement(react_bootstrap_1.Card.Header, { className: "d-flex flex-wrap justify-content-between align-items-center gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center gap-2" }, | ||
processingRef.current && (react_1.default.createElement("div", { className: "d-flex align-items-center gap-2" }, | ||
@@ -557,5 +662,10 @@ react_1.default.createElement(react_bootstrap_1.Spinner, { animation: "border", role: "status", size: "sm" }))), | ||
react_1.default.createElement(react_bootstrap_1.Form.Check, { inline: true, label: "Raw", className: "user-select-none", id: "raw-checkbox", checked: showRawOutput, onChange: (e) => setShowRawOutput(e.target.checked) }), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-primary", onClick: handleCopy }, copied ? react_1.default.createElement(fa_1.FaCheck, { className: "mb-1" }) : react_1.default.createElement(fa_1.FaCopy, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", onClick: handleClear }, | ||
react_1.default.createElement(fa_1.FaTrash, { className: "mb-1" })))), | ||
react_1.default.createElement(react_bootstrap_1.Button, { size: "sm", variant: "outline-primary", onClick: handleCopy }, copied ? react_1.default.createElement(fa_1.FaCheck, { className: "mb-1" }) : react_1.default.createElement(fa_1.FaCopy, { className: "mb-1" })), | ||
!showDeleteOutputConfirmation && (react_1.default.createElement(react_bootstrap_1.Button, { size: "sm", variant: "outline-danger", onClick: handleDeleteOutput }, | ||
react_1.default.createElement(fa_1.FaTrash, { className: "mb-1" }))), | ||
showDeleteOutputConfirmation && (react_1.default.createElement("div", { className: "d-flex align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { size: "sm", variant: "outline-danger", onClick: handleConfirmDeleteOutput }, | ||
react_1.default.createElement(fa_1.FaCheck, { className: "mb-1" })), | ||
react_1.default.createElement(react_bootstrap_1.Button, { size: "sm", variant: "outline-secondary", onClick: handleCancelDeleteOutput }, | ||
react_1.default.createElement(fa_1.FaTimes, { className: "mb-1" })))))), | ||
react_1.default.createElement(react_bootstrap_1.Card.Body, { className: "d-flex flex-column gap-2" }, | ||
@@ -576,3 +686,3 @@ !outputs && react_1.default.createElement(react_bootstrap_1.Spinner, { animation: "border", role: "status", size: "sm" }), | ||
errorAlertElements, | ||
((_h = (outputs !== null && outputs !== void 0 ? outputs : [])) === null || _h === void 0 ? void 0 : _h.length) > 0 && (react_1.default.createElement("h5", { className: "text-center text-muted" }, | ||
((_k = (outputs !== null && outputs !== void 0 ? outputs : [])) === null || _k === void 0 ? void 0 : _k.length) > 0 && (react_1.default.createElement("h5", { className: "text-center text-muted" }, | ||
"If this project helped you, please", | ||
@@ -579,0 +689,0 @@ ' ', |
@@ -97,3 +97,3 @@ "use strict"; | ||
} })), | ||
react_1.default.createElement("div", { className: "d-flex align-items-center gap-2" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center gap-2" }, | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "primary", onClick: handleCopy }, copied ? 'Copied!' : 'Copy'), | ||
@@ -100,0 +100,0 @@ react_1.default.createElement(react_bootstrap_1.Button, { variant: "primary", onClick: handleImport, disabled: !canImport }, "Import"), |
export interface Preset { | ||
name: string; | ||
description: string; | ||
aiModel: string; | ||
@@ -4,0 +5,0 @@ systemPrompt: string; |
@@ -6,6 +6,7 @@ "use strict"; | ||
{ | ||
name: 'Extract Data', | ||
name: '📖 Extract Data', | ||
description: 'Extracts data from a body of text.', | ||
aiModel: 'gpt-3.5-turbo', | ||
systemPrompt: 'You are a helpful assistant.', | ||
userPrompt: 'Extract, condense, and distill the {{Data_To_Extract}} from the following {{Document_Type}}, and list them. Do not provide a heading or commentary. Here is the {{Document_Type}}:', | ||
userPrompt: 'Extract {{Data_To_Extract}} from the following {{Document_Type}}, and format the results as {{Formatted_As}}. Do not provide a heading or commentary. Here is the {{Document_Type}}:', | ||
averageTokenLength: 4.5, | ||
@@ -16,10 +17,16 @@ requestMaxTokenRatio: 0.7, | ||
autoShrink: false, | ||
variableValues: { '{{Data_To_Extract}}': 'main points', '{{Document_Type}}': 'text' }, | ||
variableValues: { | ||
'{{Data_To_Extract}}': 'the main points', | ||
'{{Document_Type}}': 'text', | ||
'{{Formatted_As}}': 'bullet points', | ||
}, | ||
variableOptions: { | ||
'{{Data_To_Extract}}': ['key ideas', 'main points', 'strategies'], | ||
'{{Data_To_Extract}}': ['the facts', 'the ideas', 'the main points', 'the sentiment', 'the topics'], | ||
'{{Document_Type}}': ['text', 'video transcript'], | ||
'{{Formatted_As}}': ['a markdown table', 'a numbered list', 'a percentage', 'bullet points'], | ||
}, | ||
}, | ||
{ | ||
name: 'Summarize', | ||
name: '📖 Summarize', | ||
description: 'Summarizes a body of text.', | ||
aiModel: 'gpt-3.5-turbo', | ||
@@ -34,6 +41,7 @@ systemPrompt: 'You are a helpful assistant.', | ||
variableValues: { '{{Length_of_Summary}}': '1 paragraph' }, | ||
variableOptions: { '{{Length_of_Summary}}': ['1 sentence', '1 paragraph', '2 paragraphs', '3 paragraphs'] }, | ||
variableOptions: { '{{Length_of_Summary}}': ['1 paragraph', '2 paragraphs', '3 paragraphs', '1 sentence'] }, | ||
}, | ||
{ | ||
name: 'Translate Text', | ||
name: '📖 Translate Text', | ||
description: 'Translates text from one language to another.', | ||
aiModel: 'gpt-3.5-turbo', | ||
@@ -46,3 +54,3 @@ systemPrompt: 'You are a helpful assistant.', | ||
chunkPrefix: '', | ||
autoShrink: true, | ||
autoShrink: false, | ||
variableValues: { | ||
@@ -112,6 +120,7 @@ '{{Start_Language}}': 'English', | ||
{ | ||
name: 'Format Text', | ||
name: '📖 Format Text', | ||
description: 'Adds capitalization and punctuation to a body of text, without changing any words.', | ||
aiModel: 'gpt-3.5-turbo', | ||
systemPrompt: 'You are a helpful assistant.', | ||
userPrompt: 'For the following {{Document_Type}}, add punctuation and capitalize the sentences for the text. Do not change the text in any other way and do NOT add or change any words. Here is the {{Document_Type}}:', | ||
userPrompt: 'For the following {{Document_Type}}, add punctuation and capitalize the sentences of the text. Do not change the text in any other way and do NOT add or change any words. Here is the {{Document_Type}}:', | ||
averageTokenLength: 4.5, | ||
@@ -121,3 +130,3 @@ requestMaxTokenRatio: 0.4, | ||
chunkPrefix: '', | ||
autoShrink: true, | ||
autoShrink: false, | ||
variableValues: { '{{Document_Type}}': 'text' }, | ||
@@ -124,0 +133,0 @@ variableOptions: { |
@@ -58,10 +58,12 @@ "use strict"; | ||
}; | ||
const aiModelElements = mergedOpenAiModelInfos.map((model, i) => { | ||
const aiModelElements = mergedOpenAiModelInfos.map((model, i, arr) => { | ||
const disabled = !(customOpenAiModelInfos !== null && customOpenAiModelInfos !== void 0 ? customOpenAiModelInfos : []).find((m) => m.id === model.id); | ||
return (react_1.default.createElement("div", { key: `model-${i}`, className: "d-flex align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Name", value: model.name, disabled: true, readOnly: true }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Model ID", className: "font-monospace", value: model.id, disabled: true, readOnly: true }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "number", min: 0, step: 1, placeholder: "Max Tokens", value: model.maxTokens, disabled: true, style: { width: 150 } }), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", disabled: disabled, onClick: () => handleDeleteOpenAiModel(model.id) }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, null)))); | ||
return (react_1.default.createElement("div", { key: `model-${i}`, className: "d-flex flex-column gap-1" }, | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Name", value: model.name, disabled: true, style: { maxWidth: 200 }, className: "w-100", readOnly: true }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Model ID", className: "font-monospace w-100", value: model.id, disabled: true, style: { maxWidth: 200 }, readOnly: true }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "number", min: 0, step: 1, placeholder: "Max Tokens", value: model.maxTokens, disabled: true, style: { maxWidth: 150 }, className: "w-100" }), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-danger", disabled: disabled, onClick: () => handleDeleteOpenAiModel(model.id) }, | ||
react_1.default.createElement(fa_1.FaTrashAlt, null))), | ||
i < arr.length - 1 && react_1.default.createElement("hr", { className: "my-1" }))); | ||
}); | ||
@@ -98,8 +100,9 @@ const canAddOpenAiModel = !mergedOpenAiModelInfos.find((m) => m.id === newOpenAiModelId) && | ||
aiModelElements, | ||
react_1.default.createElement("div", { className: "d-flex align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Display name", value: newOpenAiModelName, onChange: (e) => setNewOpenAiModelName(e.target.value) }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Model ID", className: "font-monospace", | ||
aiModelElements.length > 0 && react_1.default.createElement("hr", { className: "my-1" }), | ||
react_1.default.createElement("div", { className: "d-flex flex-wrap align-items-center gap-1" }, | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Display name", value: newOpenAiModelName, style: { maxWidth: 200 }, className: "w-100", onChange: (e) => setNewOpenAiModelName(e.target.value) }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "text", placeholder: "Model ID", className: "font-monospace w-100", | ||
// style={{ fontSize: '80%' }} | ||
value: newOpenAiModelId, onChange: (e) => setNewOpenAiModelId(e.target.value) }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "number", min: 0, step: 1, placeholder: "Max Tokens", value: newOpenAiModelMaxTokens, onChange: (e) => setNewOpenAiModelMaxTokens(e.target.value), style: { width: 150 } }), | ||
value: newOpenAiModelId, style: { maxWidth: 200 }, onChange: (e) => setNewOpenAiModelId(e.target.value) }), | ||
react_1.default.createElement(react_bootstrap_1.Form.Control, { type: "number", min: 0, step: 1, placeholder: "Max Tokens", value: newOpenAiModelMaxTokens, onChange: (e) => setNewOpenAiModelMaxTokens(e.target.value), style: { maxWidth: 150 }, className: "w-100" }), | ||
react_1.default.createElement(react_bootstrap_1.Button, { variant: "outline-primary", onClick: handleAddNewOpenAiModel, disabled: !canAddOpenAiModel }, | ||
@@ -106,0 +109,0 @@ react_1.default.createElement(fa_1.FaPlus, null)))), |
@@ -13,2 +13,3 @@ import { AIModelInfo } from './AIModelInfo'; | ||
presetName = "presetName", | ||
presetDescription = "presetDescription", | ||
openAiModel = "openAiModel", | ||
@@ -36,2 +37,3 @@ systemPrompt = "systemPrompt", | ||
presetName: string; | ||
presetDescription: string; | ||
openAiModel: string; | ||
@@ -59,2 +61,3 @@ systemPrompt: string; | ||
presetName: import("react-storage-complete").StorageState<any>; | ||
presetDescription: import("react-storage-complete").StorageState<any>; | ||
openAiModel: import("react-storage-complete").StorageState<any>; | ||
@@ -61,0 +64,0 @@ systemPrompt: import("react-storage-complete").StorageState<any>; |
@@ -22,2 +22,3 @@ "use strict"; | ||
LocalSettingsKeys["presetName"] = "presetName"; | ||
LocalSettingsKeys["presetDescription"] = "presetDescription"; | ||
LocalSettingsKeys["openAiModel"] = "openAiModel"; | ||
@@ -45,2 +46,3 @@ LocalSettingsKeys["systemPrompt"] = "systemPrompt"; | ||
[LocalSettingsKeys.presetName]: '', | ||
[LocalSettingsKeys.presetDescription]: '', | ||
[LocalSettingsKeys.openAiModel]: AIModelInfo_1.defaultOpenAiModelInfos[0].id, | ||
@@ -74,2 +76,3 @@ [LocalSettingsKeys.systemPrompt]: 'You are a helpful assistant.', | ||
[LocalSettingsKeys.presetName]: (0, react_storage_complete_1.useLocalStorage)(LocalSettingsKeys.presetName, exports.LocalSettingsDefaults[LocalSettingsKeys.presetName], storageOptions), | ||
[LocalSettingsKeys.presetDescription]: (0, react_storage_complete_1.useLocalStorage)(LocalSettingsKeys.presetDescription, exports.LocalSettingsDefaults[LocalSettingsKeys.presetDescription], storageOptions), | ||
[LocalSettingsKeys.openAiModel]: (0, react_storage_complete_1.useLocalStorage)(LocalSettingsKeys.openAiModel, exports.LocalSettingsDefaults[LocalSettingsKeys.openAiModel], storageOptions), | ||
@@ -76,0 +79,0 @@ [LocalSettingsKeys.systemPrompt]: (0, react_storage_complete_1.useLocalStorage)(LocalSettingsKeys.systemPrompt, exports.LocalSettingsDefaults[LocalSettingsKeys.systemPrompt], storageOptions), |
{ | ||
"name": "ai-text-processor", | ||
"version": "1.0.11", | ||
"version": "1.0.12", | ||
"author": "Justin Mahar <contact@justinmahar.com>", | ||
@@ -5,0 +5,0 @@ "description": "Utility for processing text using AI. Summarize, analyze, extract, translate, format, and more! ✨", |
@@ -17,4 +17,8 @@ <h2 align="center"> | ||
## [→ Open The AI Text Processor ←](https://justinmahar.github.io/ai-text-processor/?path=/story/utilities-ai-text-processor--processor) | ||
<p align="center"> | ||
<a href="https://justinmahar.github.io/ai-text-processor/?path=/story/utilities-ai-text-processor--processor"><img src="https://raw.githubusercontent.com/justinmahar/ai-text-processor/master/screenshots/extract-data-screenshot.webp" alt="Screenshot of AI Text Processor extracting an apple pie recipe" width="450" /></a> | ||
</p> | ||
<h2 align="center"><a href="https://justinmahar.github.io/ai-text-processor/?path=/story/utilities-ai-text-processor--processor">→ Open The AI Text Processor ←</a></h2> | ||
## Overview | ||
@@ -57,3 +61,2 @@ | ||
- [→ Open The AI Text Processor ←](#-open-the-ai-text-processor-) | ||
- [Overview](#overview) | ||
@@ -60,0 +63,0 @@ - [Features include:](#features-include) |
323667
39
1913
141