@zipify/wysiwyg 3.5.0-ai-prototype → 3.5.2-ai-prototype

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.
@@ -1,12 +1,12 @@
1
1
  export const aiAdapter = {
2
- generateText: async ({ prompt, context, istruction }) => {
2
+ generateText: async ({ prompt, context, instructions }) => {
3
3
  try {
4
4
  const response = await fetch('https://mendelson-test.eu.ngrok.io/process-text', {
5
5
  method: 'POST',
6
6
  headers: {
7
7
  'Content-Type': 'application/json'
8
8
  },
9
- body: JSON.stringify({ text: prompt, context })
9
+ body: JSON.stringify({ text: prompt, context, instructions })
10
10
  });
11
11
 
12
12
  if (!response.ok) {
@@ -15,7 +15,38 @@ export const aiAdapter = {
15
15
 
16
16
  return await response.json();
17
17
  } catch (error) {
18
+ // eslint-disable-next-line no-console
18
19
  console.error('An error occurred while sending the request:', error);
19
20
  }
21
+ },
22
+
23
+ settings: {
24
+ tones: [
25
+ { id: 'expert', title: 'Expert' },
26
+ { id: 'daring', title: 'Daring' },
27
+ { id: 'playful', title: 'Playful' },
28
+ { id: 'sophisticated', title: 'Sophisticated' },
29
+ { id: 'Persuasive', title: 'Persuasive' },
30
+ { id: 'supportive', title: 'Supportive' },
31
+ { id: 'personable', title: 'Personable' },
32
+ { id: 'direct', title: 'Direct' },
33
+ { id: 'empathetic', title: 'Empathetic' },
34
+ { id: 'engaging', title: 'Engaging' },
35
+ { id: 'neutral', title: 'Neutral' }
36
+ ],
37
+ textStyles: [
38
+ { id: 'formal', title: 'Formal' },
39
+ { id: 'informal', title: 'Informal' },
40
+ { id: 'technical', title: 'Technical' },
41
+ { id: 'persuasive', title: 'Persuasive' },
42
+ { id: 'promotional', title: 'Promotional' },
43
+ { id: 'product description', title: 'Product description' },
44
+ { id: 'befits', title: 'Befits' }
45
+ ],
46
+ textLength: [
47
+ { id: '200', title: 'Short (200)' },
48
+ { id: '500', title: 'Medium (500)' },
49
+ { id: '1000', title: 'Long (1000)' }
50
+ ]
20
51
  }
21
52
  };
@@ -5,51 +5,42 @@
5
5
  </Button>
6
6
 
7
7
  <Modal class="zw-suggestion-modal" :toggler="toggler" ref="modalRef" focus-first-control>
8
-
9
8
  <AiControlHeader />
10
9
  <form class="zw-link-modal__body" @submit.prevent="generateText">
11
10
 
12
- <AiSuggestionItem
13
- v-if="isLoading"
14
- :suggestion="{ content: 'Working on it...', state: 'loading' }"
15
- />
11
+ <Icon v-if="isLoading" auto-color class="zw-ai-component__icon" name="loading" size="32px" />
16
12
 
17
- <AiSuggestionItem
18
- v-else-if="lastSuggestions"
19
- :suggestion="lastSuggestions"
20
- />
13
+ <AiSuggestionItem v-else-if="lastSuggestions" :suggestion="lastSuggestions" />
21
14
 
22
15
  <label class="zw-field__label">
23
16
  {{ textAreaLabel }}
24
17
  </label>
25
18
 
26
19
  <div class="zw-position--relative">
27
- <TextArea
28
- class="zw-margin-bottom--sm"
29
- v-model="prompt"
30
- />
20
+ <TextArea class="zw-margin-bottom--sm" v-model="prompt" />
31
21
  <Button type="submit" class="zw-ai-component__send-button">
32
22
  <Icon auto-color class="zw-ai-component__icon" name="send" size="32px" />
33
23
  </Button>
34
24
  </div>
35
25
 
26
+ <AiSettings v-model="settings" />
27
+
36
28
  <Button :disabled="!lastSuggestions" type="button" skin="primary" @click="applyText">
37
29
  Apply
38
30
  </Button>
39
31
  </form>
40
-
41
-
42
32
  </Modal>
43
33
  </div>
44
34
  </template>
45
35
 
46
36
  <script>
47
- import { computed, ref, inject, unref } from 'vue';
37
+ import { computed, ref, inject, unref, watch } from 'vue';
48
38
  import { InjectionTokens } from '../../../../injectionTokens';
49
39
  import { tooltip } from '../../../../directives';
50
40
  import { Button, Icon, Modal, TextArea, useModalToggler } from '../../../base';
51
41
  import AiControlHeader from './AiControlHeader';
52
42
  import AiSuggestionItem from './AiSuggestionItem';
43
+ import AiSettings from './AiSettings';
53
44
 
54
45
  export default {
55
46
  name: 'AiControl',
@@ -60,7 +51,8 @@ export default {
60
51
  Button,
61
52
  TextArea,
62
53
  AiControlHeader,
63
- AiSuggestionItem
54
+ AiSuggestionItem,
55
+ AiSettings
64
56
  },
65
57
 
66
58
  directives: {
@@ -75,6 +67,20 @@ export default {
75
67
  const suggestions = ref([]);
76
68
  const isLoading = ref(false);
77
69
 
70
+ const settings = ref({
71
+ tone: '',
72
+ textLength: '500',
73
+ textStyle: ''
74
+ });
75
+
76
+ if (localStorage.getItem('ai-settings')) {
77
+ settings.value = JSON.parse(localStorage.getItem('ai-settings'));
78
+ }
79
+
80
+ watch(settings, () => {
81
+ localStorage.setItem('ai-settings', JSON.stringify(settings.value));
82
+ });
83
+
78
84
  const textAreaLabel = computed(() => {
79
85
  return suggestions.value.length ? 'Tell AI what to do next…' : 'Write you request';
80
86
  });
@@ -83,7 +89,7 @@ export default {
83
89
 
84
90
  const editor = inject(InjectionTokens.EDITOR);
85
91
 
86
- const onBeforeOpened = () => {};
92
+ const onBeforeOpened = () => { };
87
93
 
88
94
  const toggler = useModalToggler({
89
95
  onBeforeOpened: () => onBeforeOpened(),
@@ -97,23 +103,29 @@ export default {
97
103
  const lastSuggestions = suggestions.value[suggestions.value.length - 1];
98
104
 
99
105
  const context = lastSuggestions ? lastSuggestions.content : '';
100
-
101
- const result = await editor.commands.generateText({ prompt: action, context });
106
+ const result = await editor.commands.generateText({
107
+ prompt: action,
108
+ context,
109
+ instructions: unref(settings)
110
+ });
102
111
 
103
112
  isLoading.value = false;
104
113
  suggestions.value.push(result);
105
114
  };
106
115
 
107
116
  const generateText = async () => {
108
- if(isLoading.value) return;
117
+ if (isLoading.value) return;
109
118
 
110
119
  isLoading.value = true;
111
120
 
112
121
  const lastSuggestions = suggestions.value[suggestions.value.length - 1];
113
122
 
114
123
  const context = lastSuggestions ? lastSuggestions.content : '';
115
-
116
- const result = await editor.commands.generateText({ prompt: prompt.value, context });
124
+ const result = await editor.commands.generateText({
125
+ prompt: prompt.value,
126
+ context,
127
+ instructions: unref(settings)
128
+ });
117
129
 
118
130
  isLoading.value = false;
119
131
  prompt.value = '';
@@ -140,7 +152,8 @@ export default {
140
152
  textAreaLabel,
141
153
  isLoading,
142
154
  onAction,
143
- applyText
155
+ applyText,
156
+ settings
144
157
  };
145
158
  }
146
159
  };
@@ -0,0 +1,137 @@
1
+ <template>
2
+ <div class="zw-selectors">
3
+ <div class="zw-ai__dropdown zw-margin-right--xs">
4
+ <FieldLabel class="zw-margin-bottom--xxs">
5
+ Tone
6
+ </FieldLabel>
7
+
8
+ <Dropdown
9
+ class="zw-margin-bottom--sm"
10
+ color="gray"
11
+ :value="settings.tone"
12
+ :options="tones"
13
+ @change="changeTone"
14
+ >
15
+ <template #option="{ option }">
16
+ <DropdownOption
17
+ class="zw-link-modal-dropdown__option"
18
+ :option="option"
19
+ />
20
+ </template>
21
+ </Dropdown>
22
+ </div>
23
+
24
+ <div class="zw-ai__dropdown zw-margin-right--xs ">
25
+ <FieldLabel class="zw-margin-bottom--xxs">
26
+ Text Style
27
+ </FieldLabel>
28
+
29
+ <Dropdown
30
+ class="zw-margin-bottom--sm"
31
+ color="gray"
32
+ :value="settings.textStyle"
33
+ :options="textStyles"
34
+ @change="changeTextStyle"
35
+ >
36
+ <template #option="{ option }">
37
+ <DropdownOption
38
+ class="zw-link-modal-dropdown__option"
39
+ :option="option"
40
+ />
41
+ </template>
42
+ </Dropdown>
43
+ </div>
44
+
45
+ <div class="zw-ai__dropdown">
46
+ <FieldLabel class="zw-margin-bottom--xxs">
47
+ Length
48
+ </FieldLabel>
49
+
50
+ <Dropdown
51
+ class="zw-margin-bottom--sm"
52
+ color="gray"
53
+ :value="settings.textLength"
54
+ :options="textLength"
55
+ @change="changeTextLength"
56
+ >
57
+ <template #option="{ option }">
58
+ <DropdownOption
59
+ class="zw-link-modal-dropdown__option"
60
+ :option="option"
61
+ />
62
+ </template>
63
+ </Dropdown>
64
+ </div>
65
+ </div>
66
+ </template>
67
+
68
+ <script>
69
+ import { computed, inject } from 'vue';
70
+ import { FieldLabel, Dropdown, DropdownOption } from '../../../base';
71
+ import { InjectionTokens } from '../../../../injectionTokens';
72
+
73
+ export default {
74
+ name: 'AiSettings',
75
+
76
+ components: {
77
+ FieldLabel,
78
+ Dropdown,
79
+ DropdownOption
80
+ },
81
+
82
+ props: {
83
+ value: {
84
+ type: Object,
85
+ default: () => ({})
86
+ }
87
+ },
88
+
89
+ setup(props, { emit }) {
90
+ const settings = computed(() => {
91
+ return {
92
+ tone: props.value.tone,
93
+ textStyle: props.value.textStyle,
94
+ textLength: props.value.textLength
95
+ };
96
+ });
97
+
98
+ const editor = inject(InjectionTokens.EDITOR);
99
+ const tones = editor.commands.getAiSettings().tones;
100
+ const textStyles = editor.commands.getAiSettings().textStyles;
101
+ const textLength = editor.commands.getAiSettings().textLength;
102
+
103
+ const changeTone = (value) => {
104
+ settings.value.tone = value;
105
+ emit('input', settings.value);
106
+ };
107
+ const changeTextStyle = (value) => {
108
+ settings.value.textStyle = value;
109
+ emit('input', settings.value);
110
+ };
111
+ const changeTextLength = (value) => {
112
+ settings.value.textLength = value;
113
+ emit('input', settings.value);
114
+ };
115
+
116
+ return {
117
+ tones,
118
+ textStyles,
119
+ textLength,
120
+ changeTone,
121
+ changeTextStyle,
122
+ changeTextLength,
123
+ settings
124
+ };
125
+ }
126
+ };
127
+ </script>
128
+
129
+ <style scoped>
130
+ .zw-selectors {
131
+ display: flex;
132
+ }
133
+
134
+ .zw-ai__dropdown {
135
+ width: 100%;
136
+ }
137
+ </style>
@@ -12,9 +12,8 @@
12
12
  </template>
13
13
 
14
14
  <script>
15
- import { inject, computed } from 'vue';
15
+ import { computed } from 'vue';
16
16
  import { Button } from '../../../base';
17
- import { InjectionTokens } from '../../../../injectionTokens';
18
17
 
19
18
  export default {
20
19
  name: 'AiSuggestionItem',
@@ -1,17 +1,18 @@
1
- import { toRef } from 'vue';
2
1
  import { Extension } from '@tiptap/vue-2';
3
2
  import { createCommand } from '../utils';
4
3
 
5
4
  export const AiComponent = Extension.create({
6
- name: 'device_manager',
5
+ name: 'ai_component',
7
6
 
8
7
  addCommands() {
9
8
  return {
10
- // _getAiAdapter: createCommand(() => toRef(this.options, 'device'))
9
+ getAiSettings: createCommand(() => {
10
+ return this.options.aiComponent.settings;
11
+ }),
11
12
 
12
- generateText: createCommand(async ({ commands }, { prompt, context }) => {
13
+ generateText: createCommand(async ({ commands }, { prompt, context, instructions }) => {
13
14
  const aiComponent = this.options.aiComponent;
14
- const result = await aiComponent.generateText({ prompt, context });
15
+ const result = await aiComponent.generateText({ prompt, context, instructions });
15
16
 
16
17
  result.content = result.content.replace(/\n/g, '');
17
18
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zipify/wysiwyg",
3
- "version": "3.5.0-ai-prototype",
3
+ "version": "3.5.2-ai-prototype",
4
4
  "description": "Zipify modification of TipTap text editor",
5
5
  "main": "dist/wysiwyg.mjs",
6
6
  "bin": {