tiptapify 0.1.5 → 0.2.0
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/README.md +1 -1
- package/dist/tiptapify.css +1 -1
- package/dist/tiptapify.mjs +30351 -26471
- package/dist/tiptapify.umd.js +57 -52
- package/index.d.ts +71 -1
- package/package.json +52 -45
- package/src/components/Tiptapify.vue +38 -1
- package/src/components/Toolbar/ai.ts +13 -0
- package/src/components/Toolbar/items.ts +2 -0
- package/src/components/editorExtensions.ts +9 -3
- package/src/components/index.ts +4 -3
- package/src/constants/style.test.ts +49 -0
- package/src/extensions/PickerEventBus.test.ts +38 -0
- package/src/extensions/components/ai/Button.vue +42 -0
- package/src/extensions/components/ai/Dialog.vue +262 -0
- package/src/extensions/components/media/link/LinkDialog.vue +5 -5
- package/src/i18n/locales/ar.json +29 -0
- package/src/i18n/locales/ch.json +29 -0
- package/src/i18n/locales/cz.json +29 -0
- package/src/i18n/locales/de.json +29 -0
- package/src/i18n/locales/en.json +29 -0
- package/src/i18n/locales/es.json +29 -0
- package/src/i18n/locales/fi.json +29 -0
- package/src/i18n/locales/fr.json +29 -0
- package/src/i18n/locales/hu.json +29 -0
- package/src/i18n/locales/it.json +29 -0
- package/src/i18n/locales/ja.json +29 -0
- package/src/i18n/locales/ko.json +29 -0
- package/src/i18n/locales/la.json +29 -0
- package/src/i18n/locales/lt.json +29 -0
- package/src/i18n/locales/nl.json +29 -0
- package/src/i18n/locales/pl.json +29 -0
- package/src/i18n/locales/pt.json +29 -0
- package/src/i18n/locales/ru.json +29 -0
- package/src/i18n/locales/se.json +29 -0
- package/src/i18n/locales/th.json +29 -0
- package/src/i18n/locales/tr.json +29 -0
- package/src/i18n/locales/uk.json +29 -0
- package/src/i18n/locales/vi.json +29 -0
- package/src/index.ts +15 -1
- package/src/types/editor.ts +74 -1
- package/src/types/toolbarTypes.ts +2 -1
- package/src/utils/helpers.test.ts +32 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
|
|
3
|
+
import TiptapifyDialog from '@tiptapify/components/UI/TiptapifyDialog.vue'
|
|
4
|
+
import defaults from '@tiptapify/constants/defaults'
|
|
5
|
+
import {
|
|
6
|
+
TiptapifyAiEditorContext,
|
|
7
|
+
TiptapifyAiMode,
|
|
8
|
+
TiptapifyAiOpenAiResponse,
|
|
9
|
+
TiptapifyAiRequest,
|
|
10
|
+
TiptapifyAiResponse,
|
|
11
|
+
TiptapifyAiResolvedOptions,
|
|
12
|
+
TiptapifyEditor,
|
|
13
|
+
variantBtnTypes,
|
|
14
|
+
variantFieldTypes
|
|
15
|
+
} from '@tiptapify/types/editor'
|
|
16
|
+
import { computed, ComputedRef, inject, PropType, Ref, ref, useTemplateRef } from 'vue'
|
|
17
|
+
import { ComposerTranslation } from 'vue-i18n'
|
|
18
|
+
|
|
19
|
+
defineProps({
|
|
20
|
+
variantBtn: { type: String as PropType<variantBtnTypes>, default() { return defaults.variantBtn } },
|
|
21
|
+
variantField: { type: String as PropType<variantFieldTypes>, default() { return defaults.variantField } },
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const editor = inject('tiptapifyEditor') as Ref<TiptapifyEditor>
|
|
25
|
+
const ai = inject('tiptapifyAi') as ComputedRef<TiptapifyAiResolvedOptions | false>
|
|
26
|
+
const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
|
|
27
|
+
|
|
28
|
+
const dialog = useTemplateRef('dialog')
|
|
29
|
+
const prompt = ref('')
|
|
30
|
+
const result = ref('')
|
|
31
|
+
const error = ref('')
|
|
32
|
+
const loading = ref(false)
|
|
33
|
+
const requestRange = ref<{ from: number, to: number } | null>(null)
|
|
34
|
+
const requestMode = ref<TiptapifyAiMode>('insert')
|
|
35
|
+
|
|
36
|
+
const aiProvider = computed(() => ai?.value ? ai.value.aiProvider : undefined)
|
|
37
|
+
const promptExamples = computed(() => ai?.value ? ai.value.promptExamples : [])
|
|
38
|
+
const isGenerateDisabled = computed(() => !aiProvider.value || !prompt.value.trim() || loading.value)
|
|
39
|
+
const isApplyDisabled = computed(() => !result.value.trim() || loading.value)
|
|
40
|
+
|
|
41
|
+
defineExpose({ showDialog })
|
|
42
|
+
|
|
43
|
+
function showDialog() {
|
|
44
|
+
prompt.value = ai?.value && ai.value.defaultPrompt ? ai.value.defaultPrompt : ''
|
|
45
|
+
result.value = ''
|
|
46
|
+
error.value = ''
|
|
47
|
+
requestRange.value = null
|
|
48
|
+
requestMode.value = 'insert'
|
|
49
|
+
|
|
50
|
+
dialog.value?.open()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function close() {
|
|
54
|
+
prompt.value = ''
|
|
55
|
+
result.value = ''
|
|
56
|
+
error.value = ''
|
|
57
|
+
requestRange.value = null
|
|
58
|
+
requestMode.value = 'insert'
|
|
59
|
+
|
|
60
|
+
dialog.value?.close()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function applyExample(examplePrompt: string) {
|
|
64
|
+
prompt.value = examplePrompt
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getSelectedText(from: number, to: number) {
|
|
68
|
+
if (from === to) {
|
|
69
|
+
return ''
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return editor.value.state.doc.textBetween(from, to, '\n')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function buildDefaultMessages(context: TiptapifyAiEditorContext) {
|
|
76
|
+
const systemPrompt = ai.value && ai.value.systemPrompt
|
|
77
|
+
? ai.value.systemPrompt
|
|
78
|
+
: 'You are an assistant inside a rich text editor. Return only the final text to insert.'
|
|
79
|
+
const contextText = context.selectedText || context.text
|
|
80
|
+
const contextLabel = context.selectedText ? 'Selected text' : 'Editor text'
|
|
81
|
+
|
|
82
|
+
return [
|
|
83
|
+
{
|
|
84
|
+
role: 'system' as const,
|
|
85
|
+
content: systemPrompt,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
role: 'user' as const,
|
|
89
|
+
content: contextText
|
|
90
|
+
? `${contextLabel}:\n${contextText}\n\nUser request:\n${context.prompt}`
|
|
91
|
+
: context.prompt,
|
|
92
|
+
},
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function buildOpenAiRequest(context: TiptapifyAiEditorContext): TiptapifyAiRequest {
|
|
97
|
+
const options = ai.value || {}
|
|
98
|
+
const request: TiptapifyAiRequest = {
|
|
99
|
+
...options.chatCompletionOptions,
|
|
100
|
+
messages: options.createMessages ? options.createMessages(context) : buildDefaultMessages(context),
|
|
101
|
+
stream: false,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (options.model) {
|
|
105
|
+
request.model = options.model
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (typeof options.temperature === 'number') {
|
|
109
|
+
request.temperature = options.temperature
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return request
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function isTiptapifyAiResponse(response: unknown): response is TiptapifyAiResponse {
|
|
116
|
+
return typeof response === 'object' && response !== null && typeof (response as TiptapifyAiResponse).content === 'string'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function isOpenAiResponse(response: unknown): response is TiptapifyAiOpenAiResponse {
|
|
120
|
+
return typeof response === 'object' && response !== null && Array.isArray((response as TiptapifyAiOpenAiResponse).choices)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getResponseContent(response: TiptapifyAiResponse | TiptapifyAiOpenAiResponse | string) {
|
|
124
|
+
let content = ''
|
|
125
|
+
|
|
126
|
+
if (typeof response === 'string') {
|
|
127
|
+
content = response
|
|
128
|
+
} else if (isTiptapifyAiResponse(response)) {
|
|
129
|
+
content = response.content
|
|
130
|
+
} else if (isOpenAiResponse(response)) {
|
|
131
|
+
content = response.choices?.[0]?.message?.content ?? response.choices?.[0]?.text ?? ''
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return content.trimStart()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function generate() {
|
|
138
|
+
if (isGenerateDisabled.value || !aiProvider.value) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
error.value = ''
|
|
143
|
+
result.value = ''
|
|
144
|
+
loading.value = true
|
|
145
|
+
|
|
146
|
+
const { from, to } = editor.value.state.selection
|
|
147
|
+
const selectedText = getSelectedText(from, to)
|
|
148
|
+
requestRange.value = selectedText ? { from, to } : null
|
|
149
|
+
requestMode.value = ai.value ? ai.value.mode ?? (selectedText ? 'replace' : 'insert') : 'insert'
|
|
150
|
+
|
|
151
|
+
const context: TiptapifyAiEditorContext = {
|
|
152
|
+
prompt: prompt.value.trim(),
|
|
153
|
+
selectedText,
|
|
154
|
+
text: selectedText || editor.value.getText(),
|
|
155
|
+
html: editor.value.getHTML(),
|
|
156
|
+
json: editor.value.getJSON(),
|
|
157
|
+
mode: requestMode.value,
|
|
158
|
+
}
|
|
159
|
+
const request = buildOpenAiRequest(context)
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
const response = await aiProvider.value(request, context)
|
|
163
|
+
result.value = getResponseContent(response)
|
|
164
|
+
} catch (err) {
|
|
165
|
+
error.value = err instanceof Error ? err.message : t('ai.error')
|
|
166
|
+
} finally {
|
|
167
|
+
loading.value = false
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function apply() {
|
|
172
|
+
if (isApplyDisabled.value) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const chain = editor.value.chain().focus()
|
|
177
|
+
if (requestRange.value) {
|
|
178
|
+
chain.deleteRange(requestRange.value)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (!requestRange.value && requestMode.value === 'append') {
|
|
182
|
+
chain.insertContentAt(editor.value.state.doc.content.size, result.value).run()
|
|
183
|
+
} else {
|
|
184
|
+
chain.insertContent(result.value).run()
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
close()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
</script>
|
|
191
|
+
|
|
192
|
+
<template>
|
|
193
|
+
<TiptapifyDialog ref="dialog" module="ai" :title="t('ai.title')" :max-width="720" @close-dialog="close">
|
|
194
|
+
<template #content>
|
|
195
|
+
<VCardText>
|
|
196
|
+
<VAlert v-if="!aiProvider" type="warning" variant="tonal" density="compact" class="mb-4">
|
|
197
|
+
{{ t('ai.unavailable') }}
|
|
198
|
+
</VAlert>
|
|
199
|
+
|
|
200
|
+
<VTextarea
|
|
201
|
+
v-model="prompt"
|
|
202
|
+
:label="t('ai.prompt')"
|
|
203
|
+
:variant="variantField"
|
|
204
|
+
:disabled="loading || !aiProvider"
|
|
205
|
+
rows="4"
|
|
206
|
+
auto-grow
|
|
207
|
+
autofocus
|
|
208
|
+
/>
|
|
209
|
+
|
|
210
|
+
<div v-if="promptExamples.length" class="mb-4">
|
|
211
|
+
<VLabel class="mb-2 d-block">
|
|
212
|
+
{{ t('ai.examples') }}
|
|
213
|
+
</VLabel>
|
|
214
|
+
<div class="d-flex flex-wrap ga-2">
|
|
215
|
+
<VChip
|
|
216
|
+
v-for="example in promptExamples"
|
|
217
|
+
:key="`${example.title}:${example.prompt}`"
|
|
218
|
+
variant="tonal"
|
|
219
|
+
:disabled="loading || !aiProvider"
|
|
220
|
+
@click="applyExample(example.prompt)"
|
|
221
|
+
>
|
|
222
|
+
{{ example.title }}
|
|
223
|
+
</VChip>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<VTextarea
|
|
228
|
+
v-model="result"
|
|
229
|
+
:label="t('ai.result')"
|
|
230
|
+
:variant="variantField"
|
|
231
|
+
:loading="loading"
|
|
232
|
+
:disabled="loading"
|
|
233
|
+
rows="5"
|
|
234
|
+
auto-grow
|
|
235
|
+
/>
|
|
236
|
+
|
|
237
|
+
<VAlert v-if="loading" type="info" variant="tonal" density="compact" class="mt-4">
|
|
238
|
+
{{ t('ai.loading') }}
|
|
239
|
+
</VAlert>
|
|
240
|
+
|
|
241
|
+
<VAlert v-if="error" type="error" variant="tonal" density="compact" class="mt-4">
|
|
242
|
+
{{ error }}
|
|
243
|
+
</VAlert>
|
|
244
|
+
</VCardText>
|
|
245
|
+
</template>
|
|
246
|
+
|
|
247
|
+
<template #actions>
|
|
248
|
+
<VCardActions>
|
|
249
|
+
<VSpacer />
|
|
250
|
+
<VBtn :variant="variantBtn" @click="close">
|
|
251
|
+
{{ t('dialog.close') }}
|
|
252
|
+
</VBtn>
|
|
253
|
+
<VBtn color="primary" :variant="variantBtn" :disabled="isGenerateDisabled" :loading="loading" @click="generate">
|
|
254
|
+
{{ t('ai.generate') }}
|
|
255
|
+
</VBtn>
|
|
256
|
+
<VBtn color="primary" :variant="variantBtn" :disabled="isApplyDisabled" @click="apply">
|
|
257
|
+
{{ t('ai.apply') }}
|
|
258
|
+
</VBtn>
|
|
259
|
+
</VCardActions>
|
|
260
|
+
</template>
|
|
261
|
+
</TiptapifyDialog>
|
|
262
|
+
</template>
|
|
@@ -21,7 +21,7 @@ const generateLinkAttrs = () => ({
|
|
|
21
21
|
href: '',
|
|
22
22
|
target: targetAttrs.value[0],
|
|
23
23
|
cssClass: '',
|
|
24
|
-
rel:
|
|
24
|
+
rel: []
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
const relAttrs = ['alternate', 'author', 'bookmark', 'external', 'help', 'license', 'me', 'next', 'nofollow', 'noopener', 'noreferrer', 'opener', 'prev', 'privacy-policy', 'search', 'tag', 'terms-of-service']
|
|
@@ -43,10 +43,10 @@ const isDisabled = computed(() => {
|
|
|
43
43
|
|
|
44
44
|
function apply() {
|
|
45
45
|
let { href, target, rel, cssClass } = attrs.value
|
|
46
|
-
|
|
46
|
+
const relStr = rel?.length ? rel.join(' ') : null
|
|
47
47
|
|
|
48
48
|
if (href) {
|
|
49
|
-
editor.value.chain().focus().extendMarkRange('link').setLink({ href, target: target.value, rel, class: cssClass }).run()
|
|
49
|
+
editor.value.chain().focus().extendMarkRange('link').setLink({ href, target: target.value, rel: relStr, class: cssClass }).run()
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
close()
|
|
@@ -61,7 +61,7 @@ function clear() {
|
|
|
61
61
|
function close() {
|
|
62
62
|
attrs.value = generateLinkAttrs()
|
|
63
63
|
|
|
64
|
-
dialog.value
|
|
64
|
+
dialog.value?.close()
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const showLink = (event: CustomEvent) => {
|
|
@@ -74,7 +74,7 @@ const showLink = (event: CustomEvent) => {
|
|
|
74
74
|
attrs.value.rel = event.detail.link?.rel?.split(' ')
|
|
75
75
|
attrs.value.cssClass = event.detail.link?.class
|
|
76
76
|
|
|
77
|
-
dialog.value
|
|
77
|
+
dialog.value?.open()
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
onMounted(() => {
|
package/src/i18n/locales/ar.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "كلمات",
|
|
174
174
|
"chars": "حروف"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/ch.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "单词",
|
|
174
174
|
"chars": "字符"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/cz.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "slova",
|
|
174
174
|
"chars": "znaky"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/de.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "Wörter",
|
|
174
174
|
"chars": "Zeichen"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/en.json
CHANGED
|
@@ -171,5 +171,34 @@
|
|
|
171
171
|
"footer": {
|
|
172
172
|
"words": "words",
|
|
173
173
|
"chars": "characters"
|
|
174
|
+
},
|
|
175
|
+
"ai": {
|
|
176
|
+
"title": "AI assistant",
|
|
177
|
+
"prompt": "Prompt",
|
|
178
|
+
"examples": "Examples",
|
|
179
|
+
"generate": "Generate",
|
|
180
|
+
"apply": "Apply",
|
|
181
|
+
"result": "Result",
|
|
182
|
+
"loading": "Generating...",
|
|
183
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
184
|
+
"error": "AI generation failed",
|
|
185
|
+
"defaultExamples": {
|
|
186
|
+
"improve": {
|
|
187
|
+
"title": "Improve writing",
|
|
188
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
189
|
+
},
|
|
190
|
+
"proofReading": {
|
|
191
|
+
"title": "Proof-reading",
|
|
192
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
193
|
+
},
|
|
194
|
+
"summarize": {
|
|
195
|
+
"title": "Summarize",
|
|
196
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
197
|
+
},
|
|
198
|
+
"expand": {
|
|
199
|
+
"title": "Expand",
|
|
200
|
+
"prompt": "Expand this into a more detailed version."
|
|
201
|
+
}
|
|
202
|
+
}
|
|
174
203
|
}
|
|
175
204
|
}
|
package/src/i18n/locales/es.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "palabras",
|
|
174
174
|
"chars": "caracteres"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/fi.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "sanaa",
|
|
174
174
|
"chars": "merkkiä"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/fr.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "mots",
|
|
174
174
|
"chars": "caractères"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/hu.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "szavak",
|
|
174
174
|
"chars": "karakterek"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|
package/src/i18n/locales/it.json
CHANGED
|
@@ -172,5 +172,34 @@
|
|
|
172
172
|
"footer": {
|
|
173
173
|
"words": "parole",
|
|
174
174
|
"chars": "caratteri"
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"title": "AI assistant",
|
|
178
|
+
"prompt": "Prompt",
|
|
179
|
+
"examples": "Examples",
|
|
180
|
+
"generate": "Generate",
|
|
181
|
+
"apply": "Apply",
|
|
182
|
+
"result": "Result",
|
|
183
|
+
"loading": "Generating...",
|
|
184
|
+
"unavailable": "Configure an AI provider to use this action",
|
|
185
|
+
"error": "AI generation failed",
|
|
186
|
+
"defaultExamples": {
|
|
187
|
+
"improve": {
|
|
188
|
+
"title": "Improve writing",
|
|
189
|
+
"prompt": "Improve the clarity and tone of this text."
|
|
190
|
+
},
|
|
191
|
+
"proofReading": {
|
|
192
|
+
"title": "Proof-reading",
|
|
193
|
+
"prompt": "Correct grammar, spelling, and punctuation without changing the meaning."
|
|
194
|
+
},
|
|
195
|
+
"summarize": {
|
|
196
|
+
"title": "Summarize",
|
|
197
|
+
"prompt": "Summarize this text in a concise paragraph."
|
|
198
|
+
},
|
|
199
|
+
"expand": {
|
|
200
|
+
"title": "Expand",
|
|
201
|
+
"prompt": "Expand this into a more detailed version."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
175
204
|
}
|
|
176
205
|
}
|