@promptbook/components 0.113.0-6 → 0.113.0-7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.es.js CHANGED
@@ -41,7 +41,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
41
41
  * @generated
42
42
  * @see https://github.com/webgptorg/promptbook
43
43
  */
44
- const PROMPTBOOK_ENGINE_VERSION = '0.113.0-6';
44
+ const PROMPTBOOK_ENGINE_VERSION = '0.113.0-7';
45
45
  /**
46
46
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
47
47
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -31165,9 +31165,9 @@ function useChatInputAreaComposer(props) {
31165
31165
  * @private function of `useChatInputAreaDictation`
31166
31166
  */
31167
31167
  function insertDictationChunk(params) {
31168
- const { currentValue, dictatedText, selectionStart, selectionEnd, shouldReplaceSelection } = params;
31168
+ const { currentValue, dictatedText, selectionStart, selectionEnd, isReplacingSelection } = params;
31169
31169
  const replaceStart = selectionStart;
31170
- const replaceEnd = shouldReplaceSelection ? selectionEnd : selectionStart;
31170
+ const replaceEnd = isReplacingSelection ? selectionEnd : selectionStart;
31171
31171
  const prefix = currentValue.slice(0, replaceStart);
31172
31172
  const suffix = currentValue.slice(replaceEnd);
31173
31173
  const previousCharacter = prefix.slice(-1);
@@ -31209,7 +31209,7 @@ function learnDictationDictionary(previousChunk, correctedChunk, previousDiction
31209
31209
  if (!previousWord || !correctedWord) {
31210
31210
  continue;
31211
31211
  }
31212
- if (previousWord.toLowerCase() !== correctedWord.toLowerCase()) {
31212
+ if (previousWord !== correctedWord) {
31213
31213
  nextDictionary[previousWord.toLowerCase()] = correctedWord;
31214
31214
  }
31215
31215
  }
@@ -31703,17 +31703,73 @@ function clearPendingStopFallbackTimeout(pendingStopFallbackRef) {
31703
31703
  pendingStopFallbackRef.current = null;
31704
31704
  }
31705
31705
  /**
31706
- * Captures whether the next finalized chunk should replace the current selection.
31706
+ * Captures where the next finalized chunk should be inserted.
31707
31707
  *
31708
31708
  * @private function of `useChatInputAreaDictation`
31709
31709
  */
31710
- function captureSelectionReplacementIntent(textareaRef, replaceSelectionOnNextFinalRef) {
31710
+ function captureDictationInsertionSelection(textareaRef, dictationInsertionSelectionRef) {
31711
31711
  const textarea = textareaRef.current;
31712
31712
  if (!textarea) {
31713
31713
  return;
31714
31714
  }
31715
- const { selectionStart, selectionEnd } = resolveTextareaSelection(textarea, 0);
31716
- replaceSelectionOnNextFinalRef.current = selectionStart !== selectionEnd;
31715
+ const { selectionStart, selectionEnd } = resolveTextareaSelection(textarea, textarea.value.length);
31716
+ dictationInsertionSelectionRef.current = {
31717
+ selectionStart,
31718
+ selectionEnd,
31719
+ isReplacingSelection: selectionStart !== selectionEnd,
31720
+ };
31721
+ }
31722
+ /**
31723
+ * Resolves the insertion range for one finalized dictation chunk.
31724
+ *
31725
+ * @private function of `useChatInputAreaDictation`
31726
+ */
31727
+ function resolveDictationInsertionSelection(textareaElement, messageContentLength, dictationInsertionSelection) {
31728
+ if (dictationInsertionSelection) {
31729
+ return dictationInsertionSelection;
31730
+ }
31731
+ const { selectionStart, selectionEnd } = resolveTextareaSelection(textareaElement, messageContentLength);
31732
+ return {
31733
+ selectionStart,
31734
+ selectionEnd,
31735
+ isReplacingSelection: selectionStart !== selectionEnd,
31736
+ };
31737
+ }
31738
+ /**
31739
+ * Removes one tracked dictated chunk from the current composer value.
31740
+ *
31741
+ * @private function of `useChatInputAreaDictation`
31742
+ */
31743
+ function removeTrackedDictationChunk(currentValue, chunk) {
31744
+ const trackedText = currentValue.slice(chunk.start, chunk.start + chunk.finalText.length);
31745
+ if (trackedText === chunk.finalText) {
31746
+ return `${currentValue.slice(0, chunk.start)}${currentValue.slice(chunk.start + chunk.finalText.length)}`;
31747
+ }
31748
+ return replaceLastOccurrence(currentValue, chunk.finalText, '');
31749
+ }
31750
+ /**
31751
+ * Replaces one tracked dictated chunk inside the current composer value.
31752
+ *
31753
+ * @private function of `useChatInputAreaDictation`
31754
+ */
31755
+ function replaceTrackedDictationChunk(currentValue, chunk, correctedChunk) {
31756
+ const trackedText = currentValue.slice(chunk.start, chunk.start + chunk.finalText.length);
31757
+ if (trackedText === chunk.finalText) {
31758
+ return `${currentValue.slice(0, chunk.start)}${correctedChunk}${currentValue.slice(chunk.start + chunk.finalText.length)}`;
31759
+ }
31760
+ return replaceLastOccurrence(currentValue, chunk.finalText, correctedChunk);
31761
+ }
31762
+ /**
31763
+ * Stores the next append position after a programmatic dictation edit.
31764
+ *
31765
+ * @private function of `useChatInputAreaDictation`
31766
+ */
31767
+ function updateDictationInsertionCaret(dictationInsertionSelectionRef, caret) {
31768
+ dictationInsertionSelectionRef.current = {
31769
+ selectionStart: caret,
31770
+ selectionEnd: caret,
31771
+ isReplacingSelection: false,
31772
+ };
31717
31773
  }
31718
31774
  /**
31719
31775
  * Produces the corrected chunk value only when a real correction should be applied.
@@ -31794,7 +31850,7 @@ function useTextareaSelectionFocus(textareaRef) {
31794
31850
  *
31795
31851
  * @private function of `useChatInputAreaDictation`
31796
31852
  */
31797
- function useChatInputAreaDictationFinalResultHandler({ textareaRef, messageContentRef, applyMessageContent, dictationSettings, dictationDictionary, replaceSelectionOnNextFinalRef, focusTextareaSelection, state, }) {
31853
+ function useChatInputAreaDictationFinalResultHandler({ textareaRef, messageContentRef, applyMessageContent, dictationSettings, dictationDictionary, dictationInsertionSelectionRef, focusTextareaSelection, state, }) {
31798
31854
  const { setDictationUiState, setDictationInterimText, setDictationError, setDictationLastFinalChunk, setDictationEditableChunk, setDictationChunks, setIsDictationPanelExpanded, } = state;
31799
31855
  return useCallback((rawText) => {
31800
31856
  const textarea = textareaRef.current;
@@ -31806,15 +31862,15 @@ function useChatInputAreaDictationFinalResultHandler({ textareaRef, messageConte
31806
31862
  if (!refinedText) {
31807
31863
  return;
31808
31864
  }
31809
- const { selectionStart, selectionEnd } = resolveTextareaSelection(textarea, previousMessageContent.length);
31865
+ const { selectionStart, selectionEnd, isReplacingSelection } = resolveDictationInsertionSelection(textarea, previousMessageContent.length, dictationInsertionSelectionRef.current);
31810
31866
  const insertion = insertDictationChunk({
31811
31867
  currentValue: previousMessageContent,
31812
31868
  dictatedText: refinedText,
31813
31869
  selectionStart,
31814
31870
  selectionEnd,
31815
- shouldReplaceSelection: replaceSelectionOnNextFinalRef.current,
31871
+ isReplacingSelection,
31816
31872
  });
31817
- replaceSelectionOnNextFinalRef.current = false;
31873
+ updateDictationInsertionCaret(dictationInsertionSelectionRef, insertion.caret);
31818
31874
  setDictationInterimText('');
31819
31875
  setDictationError(null);
31820
31876
  setDictationUiState('listening');
@@ -31834,10 +31890,10 @@ function useChatInputAreaDictationFinalResultHandler({ textareaRef, messageConte
31834
31890
  }, [
31835
31891
  applyMessageContent,
31836
31892
  dictationDictionary,
31893
+ dictationInsertionSelectionRef,
31837
31894
  dictationSettings,
31838
31895
  focusTextareaSelection,
31839
31896
  messageContentRef,
31840
- replaceSelectionOnNextFinalRef,
31841
31897
  setDictationChunks,
31842
31898
  setDictationEditableChunk,
31843
31899
  setDictationError,
@@ -31885,7 +31941,7 @@ function useChatInputAreaDictationSpeechRecognitionEventHandler({ clearPendingSt
31885
31941
  return;
31886
31942
  case 'STOP':
31887
31943
  clearPendingStopFallback();
31888
- setDictationUiState((currentState) => (currentState === 'disabled' ? currentState : 'idle'));
31944
+ setDictationUiState((currentState) => currentState === 'disabled' || currentState === 'error' ? currentState : 'idle');
31889
31945
  setDictationInterimText('');
31890
31946
  return;
31891
31947
  }
@@ -31926,13 +31982,13 @@ function useChatInputAreaDictationSpeechRecognitionLifecycle({ speechRecognition
31926
31982
  *
31927
31983
  * @private function of `useChatInputAreaDictation`
31928
31984
  */
31929
- function useChatInputAreaDictationVoiceInputControls({ speechRecognition, textareaRef, resolvedSpeechRecognitionLanguage, whisperMode, pendingStopFallbackRef, replaceSelectionOnNextFinalRef, clearPendingStopFallback, state, }) {
31985
+ function useChatInputAreaDictationVoiceInputControls({ speechRecognition, textareaRef, resolvedSpeechRecognitionLanguage, whisperMode, pendingStopFallbackRef, dictationInsertionSelectionRef, clearPendingStopFallback, state, }) {
31930
31986
  const { dictationUiState, setDictationUiState, setDictationInterimText, setDictationError } = state;
31931
31987
  const startVoiceInput = useCallback(() => {
31932
31988
  if (!speechRecognition) {
31933
31989
  return;
31934
31990
  }
31935
- captureSelectionReplacementIntent(textareaRef, replaceSelectionOnNextFinalRef);
31991
+ captureDictationInsertionSelection(textareaRef, dictationInsertionSelectionRef);
31936
31992
  setDictationError(null);
31937
31993
  setDictationInterimText('');
31938
31994
  setDictationUiState('listening');
@@ -31942,7 +31998,7 @@ function useChatInputAreaDictationVoiceInputControls({ speechRecognition, textar
31942
31998
  whisperMode,
31943
31999
  });
31944
32000
  }, [
31945
- replaceSelectionOnNextFinalRef,
32001
+ dictationInsertionSelectionRef,
31946
32002
  resolvedSpeechRecognitionLanguage,
31947
32003
  setDictationError,
31948
32004
  setDictationInterimText,
@@ -31994,7 +32050,7 @@ function useChatInputAreaDictationVoiceInputControls({ speechRecognition, textar
31994
32050
  *
31995
32051
  * @private function of `useChatInputAreaDictation`
31996
32052
  */
31997
- function useChatInputAreaDictationCorrectionHandlers({ dictationChunks, dictationLastFinalChunk, dictationEditableChunk, dictationDictionary, messageContentRef, applyMessageContent, focusTextareaSelection, setDictationChunks, setDictationLastFinalChunk, setDictationEditableChunk, setDictationDictionary, }) {
32053
+ function useChatInputAreaDictationCorrectionHandlers({ dictationChunks, dictationLastFinalChunk, dictationEditableChunk, dictationDictionary, dictationInsertionSelectionRef, messageContentRef, applyMessageContent, focusTextareaSelection, setDictationChunks, setDictationLastFinalChunk, setDictationEditableChunk, setDictationDictionary, }) {
31998
32054
  const handleBacktrackLastChunk = useCallback(() => {
31999
32055
  var _a;
32000
32056
  const previousChunks = [...dictationChunks];
@@ -32002,35 +32058,51 @@ function useChatInputAreaDictationCorrectionHandlers({ dictationChunks, dictatio
32002
32058
  if (!lastChunk) {
32003
32059
  return;
32004
32060
  }
32061
+ const nextMessageContent = removeTrackedDictationChunk(messageContentRef.current, lastChunk);
32062
+ const nextCaret = Math.min(lastChunk.start, nextMessageContent.length);
32005
32063
  setDictationChunks(previousChunks);
32006
- applyMessageContent(lastChunk.beforeValue);
32064
+ applyMessageContent(nextMessageContent);
32007
32065
  const previousFinalChunk = ((_a = previousChunks[previousChunks.length - 1]) === null || _a === void 0 ? void 0 : _a.finalText) || '';
32008
32066
  setDictationLastFinalChunk(previousFinalChunk);
32009
32067
  setDictationEditableChunk(previousFinalChunk);
32010
- focusTextareaSelection(lastChunk.start, lastChunk.start);
32068
+ updateDictationInsertionCaret(dictationInsertionSelectionRef, nextCaret);
32069
+ focusTextareaSelection(nextCaret, nextCaret);
32011
32070
  }, [
32012
32071
  applyMessageContent,
32072
+ dictationInsertionSelectionRef,
32013
32073
  dictationChunks,
32014
32074
  focusTextareaSelection,
32075
+ messageContentRef,
32015
32076
  setDictationChunks,
32016
32077
  setDictationEditableChunk,
32017
32078
  setDictationLastFinalChunk,
32018
32079
  ]);
32019
32080
  const handleApplyCorrection = useCallback(() => {
32081
+ var _a;
32020
32082
  const correctedChunk = resolveCorrectedDictationChunk(dictationEditableChunk, dictationLastFinalChunk);
32021
32083
  if (!correctedChunk) {
32022
32084
  return;
32023
32085
  }
32024
- const nextMessageContent = replaceLastOccurrence(messageContentRef.current, dictationLastFinalChunk, correctedChunk);
32086
+ const lastChunk = dictationChunks[dictationChunks.length - 1];
32087
+ const nextMessageContent = lastChunk
32088
+ ? replaceTrackedDictationChunk(messageContentRef.current, lastChunk, correctedChunk)
32089
+ : replaceLastOccurrence(messageContentRef.current, dictationLastFinalChunk, correctedChunk);
32090
+ const correctionStart = (_a = lastChunk === null || lastChunk === void 0 ? void 0 : lastChunk.start) !== null && _a !== void 0 ? _a : nextMessageContent.length;
32091
+ const correctionCaret = Math.min(correctionStart + correctedChunk.length, nextMessageContent.length);
32025
32092
  applyMessageContent(nextMessageContent);
32026
32093
  setDictationLastFinalChunk(correctedChunk);
32027
32094
  setDictationChunks((previousChunks) => replaceLastDictationChunk(previousChunks, correctedChunk));
32028
32095
  setDictationDictionary(learnDictationDictionary(dictationLastFinalChunk, correctedChunk, dictationDictionary));
32096
+ updateDictationInsertionCaret(dictationInsertionSelectionRef, correctionCaret);
32097
+ focusTextareaSelection(correctionCaret, correctionCaret);
32029
32098
  }, [
32030
32099
  applyMessageContent,
32031
32100
  dictationDictionary,
32032
32101
  dictationEditableChunk,
32102
+ dictationChunks,
32103
+ dictationInsertionSelectionRef,
32033
32104
  dictationLastFinalChunk,
32105
+ focusTextareaSelection,
32034
32106
  messageContentRef,
32035
32107
  setDictationChunks,
32036
32108
  setDictationDictionary,
@@ -32048,7 +32120,7 @@ function useChatInputAreaDictationCorrectionHandlers({ dictationChunks, dictatio
32048
32120
  */
32049
32121
  function useChatInputAreaDictation({ speechRecognition, speechRecognitionLanguage, textareaRef, messageContentRef, applyMessageContent, }) {
32050
32122
  const pendingStopFallbackRef = useRef(null);
32051
- const replaceSelectionOnNextFinalRef = useRef(false);
32123
+ const dictationInsertionSelectionRef = useRef(null);
32052
32124
  const [dictationUiState, setDictationUiState] = useState('idle');
32053
32125
  const [dictationInterimText, setDictationInterimText] = useState('');
32054
32126
  const [dictationError, setDictationError] = useState(null);
@@ -32081,7 +32153,7 @@ function useChatInputAreaDictation({ speechRecognition, speechRecognitionLanguag
32081
32153
  applyMessageContent,
32082
32154
  dictationSettings,
32083
32155
  dictationDictionary,
32084
- replaceSelectionOnNextFinalRef,
32156
+ dictationInsertionSelectionRef,
32085
32157
  focusTextareaSelection,
32086
32158
  state: dictationState,
32087
32159
  });
@@ -32101,7 +32173,7 @@ function useChatInputAreaDictation({ speechRecognition, speechRecognitionLanguag
32101
32173
  resolvedSpeechRecognitionLanguage,
32102
32174
  whisperMode: dictationSettings.whisperMode,
32103
32175
  pendingStopFallbackRef,
32104
- replaceSelectionOnNextFinalRef,
32176
+ dictationInsertionSelectionRef,
32105
32177
  clearPendingStopFallback,
32106
32178
  state: {
32107
32179
  dictationUiState,
@@ -32115,6 +32187,7 @@ function useChatInputAreaDictation({ speechRecognition, speechRecognitionLanguag
32115
32187
  dictationLastFinalChunk,
32116
32188
  dictationEditableChunk,
32117
32189
  dictationDictionary,
32190
+ dictationInsertionSelectionRef,
32118
32191
  messageContentRef,
32119
32192
  applyMessageContent,
32120
32193
  focusTextareaSelection,