strapi-llm-translator 0.9.6 → 0.11.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.
Files changed (41) hide show
  1. package/README.md +21 -6
  2. package/dist/_chunks/App-A-EjjKPQ.js +252 -0
  3. package/dist/_chunks/App-A-EjjKPQ.js.map +1 -0
  4. package/dist/_chunks/App-Boy_i56G.mjs +1 -0
  5. package/dist/_chunks/App-Boy_i56G.mjs.map +1 -0
  6. package/dist/_chunks/App-COSMdnpL.js +1 -0
  7. package/dist/_chunks/App-COSMdnpL.js.map +1 -0
  8. package/dist/_chunks/App-OUCb1msi.mjs +252 -0
  9. package/dist/_chunks/App-OUCb1msi.mjs.map +1 -0
  10. package/dist/_chunks/de-CvAR4QXO.js +1 -0
  11. package/dist/_chunks/de-CvAR4QXO.js.map +1 -0
  12. package/dist/_chunks/de-D3VSS3Mq.mjs +1 -0
  13. package/dist/_chunks/de-D3VSS3Mq.mjs.map +1 -0
  14. package/dist/_chunks/en-BjVvIBv8.js +1 -0
  15. package/dist/_chunks/en-BjVvIBv8.js.map +1 -0
  16. package/dist/_chunks/en-BnBUQVgF.mjs +1 -0
  17. package/dist/_chunks/en-BnBUQVgF.mjs.map +1 -0
  18. package/dist/_chunks/index-BEhzLY5B.mjs +1 -0
  19. package/dist/_chunks/index-BEhzLY5B.mjs.map +1 -0
  20. package/dist/_chunks/index-C7I5p1ip.js +277 -0
  21. package/dist/_chunks/index-C7I5p1ip.js.map +1 -0
  22. package/dist/_chunks/index-DuLkx3CK.js +1 -0
  23. package/dist/_chunks/index-DuLkx3CK.js.map +1 -0
  24. package/dist/_chunks/index-RMoTs0Ce.mjs +278 -0
  25. package/dist/_chunks/index-RMoTs0Ce.mjs.map +1 -0
  26. package/dist/admin/index.js +2 -1
  27. package/dist/admin/index.js.map +1 -0
  28. package/dist/admin/index.mjs +2 -1
  29. package/dist/admin/index.mjs.map +1 -0
  30. package/dist/server/index.js +97 -45
  31. package/dist/server/index.js.map +1 -0
  32. package/dist/server/index.mjs +97 -45
  33. package/dist/server/index.mjs.map +1 -0
  34. package/dist/server/src/config/constants.d.ts +3 -0
  35. package/dist/server/src/config/index.d.ts +8 -5
  36. package/dist/server/src/controllers/admin.controller.d.ts +1 -1
  37. package/dist/server/src/controllers/index.d.ts +1 -1
  38. package/dist/server/src/index.d.ts +9 -6
  39. package/dist/server/src/types/controllers.d.ts +1 -1
  40. package/dist/server/src/types/index.d.ts +5 -0
  41. package/package.json +11 -11
package/README.md CHANGED
@@ -7,7 +7,7 @@ The Strapi LLM Translator plugin enhances your localization workflow by utilisin
7
7
  ## 🚀 Key Features
8
8
 
9
9
  - 🌍 **Multi-field Support** - Translates all text-based fields (string, text, richtext) and JSON/Blocks content, including Strapi 5 structured rich text
10
- - 🔌 **LLM Agnostic** - Works with any OpenAI-compatible API (your choice of provider)
10
+ - 🔌 **LLM Agnostic** - Works with any OpenAI-compatible API (your choice of provider or local)
11
11
  - 📝 **Format Preservation** - Maintains markdown formatting during translation
12
12
  - 🔗 **Smart UUID Handling** - Auto-translates slugs when i18n is enabled with relative fields
13
13
  - ⚡ **Auto-fill** - Instantly populates generated translations
@@ -21,17 +21,19 @@ The Strapi LLM Translator plugin enhances your localization workflow by utilisin
21
21
 
22
22
  ## ✅ Tested With
23
23
 
24
- - **Strapi**: v5.12.x
24
+ - **Strapi**: v5.12.x, v5.15.x
25
25
  - **LLM Providers**:
26
26
  - OpenAI: `gpt-4o`
27
+ - Azure OpenAI: `gpt-4.1`
27
28
  - Groq: `meta-llama/llama-4-scout-17b-16e-instruct`
29
+ - Local: `Ollama`, e.g. `phi4-mini`
28
30
 
29
31
  ## 🛠️ Installation & Setup
30
32
 
31
33
  ### Prerequisites
32
34
 
33
35
  - Strapi project (v5+)
34
- - API key for your preferred LLM provider, opt. BaseUrl + model name
36
+ - API key for your preferred LLM provider, Base Url + Model Name (+ API Version for Azure OpenAI)
35
37
  - Configured internationalization with at least two languages in your Strapi application
36
38
 
37
39
  ### Installation
@@ -45,12 +47,15 @@ npm install strapi-llm-translator
45
47
  2. Configure environment variables:
46
48
 
47
49
  ```
48
- # Required - Your LLM provider API key
50
+ # Optional - Your LLM provider API key (Can be left empty if there is no API Key needed)
49
51
  LLM_TRANSLATOR_LLM_API_KEY=
50
52
 
51
53
  # Optional - Defaults to OpenAI's endpoint
52
54
  STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL=
53
55
 
56
+ # Optional - ⚠️ Only Required for Azure OpenAI
57
+ STRAPI_ADMIN_LLM_TRANSLATOR_AZURE_API_VERSION=
58
+
54
59
  # Optional - Defaults to gpt-4o
55
60
  STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL=
56
61
  ```
@@ -79,9 +84,19 @@ To contribute to the plugin development:
79
84
  4. In a separate terminal, watch the plugin for changes:
80
85
  `npm run watch:link`
81
86
 
82
- ## About
87
+ ## Contributors ✨
88
+
89
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
90
+
91
+ <!-- You can use the all-contributors bot or just list them manually -->
92
+
93
+ - [jacco-webleads](https://github.com/jacco-webleads) (Parallel Batch Processing)
94
+ - [asiegrist](https://github.com/asiegrist) (Azure OpenAI Support)
95
+ - [DrTimmi](https://github.com/DrTimmi) (Support for nested components, dynamic zones, rich-text fields, and robust JSON parsing)
96
+
97
+ ## Author
83
98
 
84
- Franziska Fieke ([grenzbotin](https://github.com/grenzbotin)) – [vulpis.dev](https://vulpis.dev)
99
+ - [grenzbotin](https://github.com/grenzbotin) – [vulpis.dev](https://vulpis.dev)
85
100
 
86
101
  Distributed under the MIT license.
87
102
  See `LICENSE` for more information.
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const admin = require("@strapi/strapi/admin");
5
+ const reactRouterDom = require("react-router-dom");
6
+ const designSystem = require("@strapi/design-system");
7
+ const reactIntl = require("react-intl");
8
+ const react = require("react");
9
+ const index = require("./index-C7I5p1ip.js");
10
+ const DEFAULT_SYSTEM_PROMPT = "You are a professional translator. Your task is to translate the provided content accurately while preserving the original meaning and tone.";
11
+ const DEFAULT_LLM_TEMPERATURE = 0.3;
12
+ const MAX_LLM_TEMPERATURE = 2;
13
+ const MIN_LLM_TEMPERATURE = 0.1;
14
+ const HomePage = () => {
15
+ const [config, setConfig] = react.useState({ systemPrompt: "", temperature: 0.3 });
16
+ const { formatMessage } = reactIntl.useIntl();
17
+ const { get, post } = admin.useFetchClient();
18
+ react.useEffect(() => {
19
+ const fetchData = async () => {
20
+ const response = await get(`/${index.PLUGIN_ID}/config`);
21
+ setConfig({ ...config, ...response.data });
22
+ };
23
+ fetchData();
24
+ }, []);
25
+ const handleSubmit = async (e) => {
26
+ e.preventDefault();
27
+ await post(`/${index.PLUGIN_ID}/config`, { ...config });
28
+ };
29
+ const handleRestore = async () => {
30
+ setConfig({ systemPrompt: DEFAULT_SYSTEM_PROMPT, temperature: DEFAULT_LLM_TEMPERATURE });
31
+ await post(`/${index.PLUGIN_ID}/config`, {
32
+ systemPrompt: DEFAULT_SYSTEM_PROMPT,
33
+ temperature: DEFAULT_LLM_TEMPERATURE
34
+ });
35
+ };
36
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { children: [
37
+ /* @__PURE__ */ jsxRuntime.jsxs(
38
+ designSystem.Box,
39
+ {
40
+ paddingLeft: 10,
41
+ paddingRight: 10,
42
+ paddingBottom: 8,
43
+ paddingTop: 8,
44
+ "data-strapi-header": true,
45
+ background: "neutral100",
46
+ children: [
47
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { "data-strapi-header": true, alignItems: "center", gap: 3, marginBottom: 4, children: [
48
+ /* @__PURE__ */ jsxRuntime.jsx(index.PluginIcon, { width: 42, height: 42 }),
49
+ " ",
50
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", fontWeight: "bold", children: formatMessage({
51
+ id: index.getTranslation("plugin.page.title"),
52
+ defaultMessage: "LLM Translator (Configuration)"
53
+ }) })
54
+ ] }),
55
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", textColor: "neutral600", fontWeight: "normal", children: formatMessage({
56
+ id: index.getTranslation("plugin.page.description"),
57
+ defaultMessage: "Configure the LLM Translator plugin settings. Be aware that Base Model, API Key and LLM Base URL need to be set as environment variables."
58
+ }) })
59
+ ]
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 10, paddingRight: 10, children: /* @__PURE__ */ jsxRuntime.jsx(
63
+ designSystem.Box,
64
+ {
65
+ paddingLeft: 10,
66
+ paddingRight: 10,
67
+ paddingTop: 8,
68
+ paddingBottom: 8,
69
+ background: "neutral0",
70
+ children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
71
+ /* @__PURE__ */ jsxRuntime.jsxs(
72
+ designSystem.Field.Root,
73
+ {
74
+ id: "system_prompt",
75
+ hint: formatMessage({
76
+ id: index.getTranslation("plugin.page.form.system_prompt_hint"),
77
+ defaultMessage: "This is (part) of the prompt that will be used to instruct the LLM. It should be clear and concise."
78
+ }),
79
+ required: true,
80
+ children: [
81
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
82
+ id: index.getTranslation("plugin.page.form.system_prompt"),
83
+ defaultMessage: "System prompt"
84
+ }) }),
85
+ /* @__PURE__ */ jsxRuntime.jsx(
86
+ designSystem.Textarea,
87
+ {
88
+ id: "system_prompt",
89
+ value: config.systemPrompt,
90
+ onChange: (e) => setConfig({ ...config, systemPrompt: e.target.value }),
91
+ required: true,
92
+ placeholder: DEFAULT_SYSTEM_PROMPT,
93
+ name: "system_prompt"
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {}),
97
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
98
+ ]
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, marginTop: 6, flex: 1, children: [
102
+ /* @__PURE__ */ jsxRuntime.jsxs(
103
+ designSystem.Field.Root,
104
+ {
105
+ id: "llm_temperature",
106
+ hint: formatMessage({
107
+ id: index.getTranslation("plugin.page.form.llm_temperature_hint"),
108
+ defaultMessage: "Temperature setting for the LLM. A higher value will make the output more random, while a lower value will make it more focused and deterministic."
109
+ }),
110
+ flex: 1,
111
+ children: [
112
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
113
+ id: index.getTranslation("plugin.page.form.llm_temperature"),
114
+ defaultMessage: "LLM Temperature"
115
+ }) }),
116
+ /* @__PURE__ */ jsxRuntime.jsx(
117
+ designSystem.NumberInput,
118
+ {
119
+ id: "llm_temperature",
120
+ value: config.temperature,
121
+ name: "llm_temperature",
122
+ step: 0.1,
123
+ min: MIN_LLM_TEMPERATURE,
124
+ max: MAX_LLM_TEMPERATURE,
125
+ onValueChange: (value) => {
126
+ let tempValue = DEFAULT_LLM_TEMPERATURE;
127
+ if (value === void 0) {
128
+ tempValue = DEFAULT_LLM_TEMPERATURE;
129
+ } else if (value < MIN_LLM_TEMPERATURE) {
130
+ tempValue = MIN_LLM_TEMPERATURE;
131
+ } else if (value > MAX_LLM_TEMPERATURE) {
132
+ tempValue = MAX_LLM_TEMPERATURE;
133
+ } else {
134
+ tempValue = value;
135
+ }
136
+ setConfig({ ...config, temperature: tempValue });
137
+ }
138
+ }
139
+ ),
140
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {}),
141
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
142
+ ]
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsxRuntime.jsxs(
146
+ designSystem.Field.Root,
147
+ {
148
+ id: "llm_model",
149
+ flex: 1,
150
+ hint: formatMessage({
151
+ id: index.getTranslation("plugin.page.form.llm_model_hint"),
152
+ defaultMessage: "Model that will be used to generate the translations. It should be set as an environment variable."
153
+ }),
154
+ children: [
155
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
156
+ id: index.getTranslation("plugin.page.form.llm_model"),
157
+ defaultMessage: "LLM Model"
158
+ }) }),
159
+ /* @__PURE__ */ jsxRuntime.jsx(
160
+ designSystem.TextInput,
161
+ {
162
+ id: "llm_model",
163
+ value: process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL,
164
+ disabled: true,
165
+ name: "llm_model"
166
+ }
167
+ ),
168
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {}),
169
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
170
+ ]
171
+ }
172
+ ),
173
+ /* @__PURE__ */ jsxRuntime.jsxs(
174
+ designSystem.Field.Root,
175
+ {
176
+ id: "llm_base_url",
177
+ flex: 1,
178
+ hint: formatMessage({
179
+ id: index.getTranslation("plugin.page.form.llm_base_url_hint"),
180
+ defaultMessage: "Base URL for the LLM API. It needs to be set as an environment variable."
181
+ }),
182
+ children: [
183
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
184
+ id: index.getTranslation("plugin.page.form.llm_base_url"),
185
+ defaultMessage: "LLM Base Url"
186
+ }) }),
187
+ /* @__PURE__ */ jsxRuntime.jsx(
188
+ designSystem.TextInput,
189
+ {
190
+ id: "llm_base_url",
191
+ value: process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL,
192
+ disabled: true,
193
+ name: "llm_base_url"
194
+ }
195
+ ),
196
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {}),
197
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
198
+ ]
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsxRuntime.jsxs(
202
+ designSystem.Field.Root,
203
+ {
204
+ id: "llm_api_version",
205
+ flex: 1,
206
+ hint: formatMessage({
207
+ id: index.getTranslation("plugin.page.form.llm_api_version_hint"),
208
+ defaultMessage: "⚠️ Required to enable Azure OpenAI. Azure API Version for the LLM API. It needs to be set as an environment variable."
209
+ }),
210
+ children: [
211
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
212
+ id: index.getTranslation("plugin.page.form.llm_api_version"),
213
+ defaultMessage: "LLM Azure API Version"
214
+ }) }),
215
+ /* @__PURE__ */ jsxRuntime.jsx(
216
+ designSystem.TextInput,
217
+ {
218
+ id: "llm_api_version",
219
+ value: process.env.STRAPI_ADMIN_LLM_TRANSLATOR_AZURE_API_VERSION,
220
+ disabled: true,
221
+ name: "llm_api_version"
222
+ }
223
+ ),
224
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {}),
225
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
226
+ ]
227
+ }
228
+ )
229
+ ] }),
230
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, marginTop: 6, justifyContent: "flex-end", children: [
231
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", type: "button", onClick: handleRestore, marginTop: 4, children: formatMessage({
232
+ id: index.getTranslation("plugin.page.form.restore"),
233
+ defaultMessage: "Restore to default"
234
+ }) }),
235
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "default", type: "submit", marginTop: 4, children: formatMessage({
236
+ id: index.getTranslation("plugin.page.form.save"),
237
+ defaultMessage: "Save"
238
+ }) })
239
+ ] })
240
+ ] })
241
+ }
242
+ ) })
243
+ ] });
244
+ };
245
+ const App = () => {
246
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
247
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(HomePage, {}) }),
248
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "*", element: /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Error, {}) })
249
+ ] });
250
+ };
251
+ exports.App = App;
252
+ //# sourceMappingURL=App-A-EjjKPQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App-A-EjjKPQ.js","sources":["../../admin/src/utils/constants.ts","../../admin/src/pages/HomePage.tsx","../../admin/src/pages/App.tsx"],"sourcesContent":["export const DEFAULT_SYSTEM_PROMPT =\n 'You are a professional translator. Your task is to translate the provided content accurately while preserving the original meaning and tone.';\n\nexport const DEFAULT_LLM_TEMPERATURE = 0.3;\n\nexport const MAX_LLM_TEMPERATURE = 2;\nexport const MIN_LLM_TEMPERATURE = 0.1;\n","import {\n Box,\n Button,\n Field,\n Flex,\n Main,\n Typography,\n Textarea,\n TextInput,\n NumberInput,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { useEffect, useState } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\nimport { getTranslation } from '../utils/getTranslation';\nimport { PLUGIN_ID } from '../../src/pluginId';\nimport { PluginConfig } from '../../custom';\nimport { PluginIcon } from '../../src/components/PluginIcon';\nimport {\n DEFAULT_LLM_TEMPERATURE,\n DEFAULT_SYSTEM_PROMPT,\n MAX_LLM_TEMPERATURE,\n MIN_LLM_TEMPERATURE,\n} from '../utils/constants';\n\ninterface FormEvent extends React.FormEvent<HTMLFormElement> {\n preventDefault(): void;\n}\n\nconst HomePage = () => {\n const [config, setConfig] = useState({ systemPrompt: '', temperature: 0.3 });\n const { formatMessage } = useIntl();\n const { get, post } = useFetchClient();\n\n useEffect(() => {\n // Fetch current config\n const fetchData = async () => {\n const response = await get(`/${PLUGIN_ID}/config`);\n setConfig({ ...config, ...response.data });\n };\n fetchData();\n }, []);\n\n const handleSubmit = async (e: FormEvent): Promise<void> => {\n e.preventDefault();\n await post(`/${PLUGIN_ID}/config`, { ...(config as PluginConfig) });\n };\n\n const handleRestore = async (): Promise<void> => {\n setConfig({ systemPrompt: DEFAULT_SYSTEM_PROMPT, temperature: DEFAULT_LLM_TEMPERATURE });\n await post(`/${PLUGIN_ID}/config`, {\n systemPrompt: DEFAULT_SYSTEM_PROMPT,\n temperature: DEFAULT_LLM_TEMPERATURE,\n });\n };\n\n return (\n <Main>\n <Box\n paddingLeft={10}\n paddingRight={10}\n paddingBottom={8}\n paddingTop={8}\n data-strapi-header\n background=\"neutral100\"\n >\n <Flex data-strapi-header alignItems=\"center\" gap={3} marginBottom={4}>\n <PluginIcon width={42} height={42} />{' '}\n <Typography variant=\"alpha\" tag=\"h1\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslation('plugin.page.title'),\n defaultMessage: 'LLM Translator (Configuration)',\n })}\n </Typography>\n </Flex>\n <Typography variant=\"delta\" textColor=\"neutral600\" fontWeight=\"normal\">\n {formatMessage({\n id: getTranslation('plugin.page.description'),\n defaultMessage:\n 'Configure the LLM Translator plugin settings. Be aware that Base Model, API Key and LLM Base URL need to be set as environment variables.',\n })}\n </Typography>\n </Box>\n\n <Box paddingLeft={10} paddingRight={10}>\n <Box\n paddingLeft={10}\n paddingRight={10}\n paddingTop={8}\n paddingBottom={8}\n background=\"neutral0\"\n >\n <form onSubmit={handleSubmit}>\n <Field.Root\n id=\"system_prompt\"\n hint={formatMessage({\n id: getTranslation('plugin.page.form.system_prompt_hint'),\n defaultMessage:\n 'This is (part) of the prompt that will be used to instruct the LLM. It should be clear and concise.',\n })}\n required\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.system_prompt'),\n defaultMessage: 'System prompt',\n })}\n </Field.Label>\n <Textarea\n id=\"system_prompt\"\n value={config.systemPrompt as string}\n onChange={(e: { target: { value: string } }) =>\n setConfig({ ...config, systemPrompt: e.target.value })\n }\n required\n placeholder={DEFAULT_SYSTEM_PROMPT}\n name=\"system_prompt\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Flex gap={4} marginTop={6} flex={1}>\n <Field.Root\n id=\"llm_temperature\"\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_temperature_hint'),\n defaultMessage:\n 'Temperature setting for the LLM. A higher value will make the output more random, while a lower value will make it more focused and deterministic.',\n })}\n flex={1}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_temperature'),\n defaultMessage: 'LLM Temperature',\n })}\n </Field.Label>\n <NumberInput\n id=\"llm_temperature\"\n value={config.temperature}\n name=\"llm_temperature\"\n step={0.1}\n min={MIN_LLM_TEMPERATURE}\n max={MAX_LLM_TEMPERATURE}\n onValueChange={(value: number | undefined) => {\n let tempValue = DEFAULT_LLM_TEMPERATURE;\n if (value === undefined) {\n tempValue = DEFAULT_LLM_TEMPERATURE;\n } else if (value < MIN_LLM_TEMPERATURE) {\n tempValue = MIN_LLM_TEMPERATURE;\n } else if (value > MAX_LLM_TEMPERATURE) {\n tempValue = MAX_LLM_TEMPERATURE;\n } else {\n tempValue = value;\n }\n\n setConfig({ ...config, temperature: tempValue });\n }}\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_model\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_model_hint'),\n defaultMessage:\n 'Model that will be used to generate the translations. It should be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_model'),\n defaultMessage: 'LLM Model',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_model\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL as string}\n disabled\n name=\"llm_model\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_base_url\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_base_url_hint'),\n defaultMessage:\n 'Base URL for the LLM API. It needs to be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_base_url'),\n defaultMessage: 'LLM Base Url',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_base_url\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL as string}\n disabled\n name=\"llm_base_url\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_api_version\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_api_version_hint'),\n defaultMessage:\n '⚠️ Required to enable Azure OpenAI. Azure API Version for the LLM API. It needs to be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_api_version'),\n defaultMessage: 'LLM Azure API Version',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_api_version\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_AZURE_API_VERSION as string}\n disabled\n name=\"llm_api_version\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n </Flex>\n <Flex gap={2} marginTop={6} justifyContent=\"flex-end\">\n <Button variant=\"secondary\" type=\"button\" onClick={handleRestore} marginTop={4}>\n {formatMessage({\n id: getTranslation('plugin.page.form.restore'),\n defaultMessage: 'Restore to default',\n })}\n </Button>\n\n <Button variant=\"default\" type=\"submit\" marginTop={4}>\n {formatMessage({\n id: getTranslation('plugin.page.form.save'),\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </form>\n </Box>\n </Box>\n </Main>\n );\n};\n\nexport { HomePage };\n","import { Page } from '@strapi/strapi/admin';\nimport { Routes, Route } from 'react-router-dom';\n\nimport { HomePage } from './HomePage';\n\nconst App = () => {\n return (\n <Routes>\n <Route index element={<HomePage />} />\n <Route path=\"*\" element={<Page.Error />} />\n </Routes>\n );\n};\n\nexport { App };\n"],"names":["useState","useIntl","useFetchClient","useEffect","PLUGIN_ID","Main","jsxs","Box","Flex","jsx","PluginIcon","Typography","getTranslation","Field","Textarea","NumberInput","TextInput","Button","Routes","Route","Page"],"mappings":"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"}
@@ -221,3 +221,4 @@ const App = () => {
221
221
  export {
222
222
  App
223
223
  };
224
+ //# sourceMappingURL=App-Boy_i56G.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App-Boy_i56G.mjs","sources":["../../admin/src/utils/constants.ts","../../admin/src/pages/HomePage.tsx","../../admin/src/pages/App.tsx"],"sourcesContent":["export const DEFAULT_SYSTEM_PROMPT =\n 'You are a professional translator. Your task is to translate the provided content accurately while preserving the original meaning and tone.';\n\nexport const DEFAULT_LLM_TEMPERATURE = 0.3;\n\nexport const MAX_LLM_TEMPERATURE = 2;\nexport const MIN_LLM_TEMPERATURE = 0.1;\n","import {\n Box,\n Button,\n Field,\n Flex,\n Main,\n Typography,\n Textarea,\n TextInput,\n NumberInput,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { useEffect, useState } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\nimport { getTranslation } from '../utils/getTranslation';\nimport { PLUGIN_ID } from '../../src/pluginId';\nimport { PluginConfig } from '../../custom';\nimport { PluginIcon } from '../../src/components/PluginIcon';\nimport {\n DEFAULT_LLM_TEMPERATURE,\n DEFAULT_SYSTEM_PROMPT,\n MAX_LLM_TEMPERATURE,\n MIN_LLM_TEMPERATURE,\n} from '../utils/constants';\n\ninterface FormEvent extends React.FormEvent<HTMLFormElement> {\n preventDefault(): void;\n}\n\nconst HomePage = () => {\n const [config, setConfig] = useState({ systemPrompt: '', temperature: 0.3 });\n const { formatMessage } = useIntl();\n const { get, post } = useFetchClient();\n\n useEffect(() => {\n // Fetch current config\n const fetchData = async () => {\n const response = await get(`/${PLUGIN_ID}/config`);\n setConfig({ ...config, ...response.data });\n };\n fetchData();\n }, []);\n\n const handleSubmit = async (e: FormEvent): Promise<void> => {\n e.preventDefault();\n await post(`/${PLUGIN_ID}/config`, { ...(config as PluginConfig) });\n };\n\n const handleRestore = async (): Promise<void> => {\n setConfig({ systemPrompt: DEFAULT_SYSTEM_PROMPT, temperature: DEFAULT_LLM_TEMPERATURE });\n await post(`/${PLUGIN_ID}/config`, {\n systemPrompt: DEFAULT_SYSTEM_PROMPT,\n temperature: DEFAULT_LLM_TEMPERATURE,\n });\n };\n\n return (\n <Main>\n <Box\n paddingLeft={10}\n paddingRight={10}\n paddingBottom={8}\n paddingTop={8}\n data-strapi-header\n background=\"neutral100\"\n >\n <Flex data-strapi-header alignItems=\"center\" gap={3} marginBottom={4}>\n <PluginIcon width={42} height={42} />{' '}\n <Typography variant=\"alpha\" tag=\"h1\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslation('plugin.page.title'),\n defaultMessage: 'LLM Translator (Configuration)',\n })}\n </Typography>\n </Flex>\n <Typography variant=\"delta\" textColor=\"neutral600\" fontWeight=\"normal\">\n {formatMessage({\n id: getTranslation('plugin.page.description'),\n defaultMessage:\n 'Configure the LLM Translator plugin settings. Be aware that Base Model, API Key and LLM Base URL need to be set as environment variables.',\n })}\n </Typography>\n </Box>\n\n <Box paddingLeft={10} paddingRight={10}>\n <Box\n paddingLeft={10}\n paddingRight={10}\n paddingTop={8}\n paddingBottom={8}\n background=\"neutral0\"\n >\n <form onSubmit={handleSubmit}>\n <Field.Root\n id=\"system_prompt\"\n hint={formatMessage({\n id: getTranslation('plugin.page.form.system_prompt_hint'),\n defaultMessage:\n 'This is (part) of the prompt that will be used to instruct the LLM. It should be clear and concise.',\n })}\n required\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.system_prompt'),\n defaultMessage: 'System prompt',\n })}\n </Field.Label>\n <Textarea\n id=\"system_prompt\"\n value={config.systemPrompt as string}\n onChange={(e: { target: { value: string } }) =>\n setConfig({ ...config, systemPrompt: e.target.value })\n }\n required\n placeholder={DEFAULT_SYSTEM_PROMPT}\n name=\"system_prompt\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Flex gap={4} marginTop={6} flex={1}>\n <Field.Root\n id=\"llm_temperature\"\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_temperature_hint'),\n defaultMessage:\n 'Temperature setting for the LLM. A higher value will make the output more random, while a lower value will make it more focused and deterministic.',\n })}\n flex={1}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_temperature'),\n defaultMessage: 'LLM Temperature',\n })}\n </Field.Label>\n <NumberInput\n id=\"llm_temperature\"\n value={config.temperature}\n name=\"llm_temperature\"\n step={0.1}\n min={MIN_LLM_TEMPERATURE}\n max={MAX_LLM_TEMPERATURE}\n onValueChange={(value: number | undefined) => {\n let tempValue = DEFAULT_LLM_TEMPERATURE;\n if (value === undefined) {\n tempValue = DEFAULT_LLM_TEMPERATURE;\n } else if (value < MIN_LLM_TEMPERATURE) {\n tempValue = MIN_LLM_TEMPERATURE;\n } else if (value > MAX_LLM_TEMPERATURE) {\n tempValue = MAX_LLM_TEMPERATURE;\n } else {\n tempValue = value;\n }\n\n setConfig({ ...config, temperature: tempValue });\n }}\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_model\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_model_hint'),\n defaultMessage:\n 'Model that will be used to generate the translations. It should be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_model'),\n defaultMessage: 'LLM Model',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_model\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL as string}\n disabled\n name=\"llm_model\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_base_url\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_base_url_hint'),\n defaultMessage:\n 'Base URL for the LLM API. It needs to be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_base_url'),\n defaultMessage: 'LLM Base Url',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_base_url\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL as string}\n disabled\n name=\"llm_base_url\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n </Flex>\n <Flex gap={2} marginTop={6} justifyContent=\"flex-end\">\n <Button variant=\"secondary\" type=\"button\" onClick={handleRestore} marginTop={4}>\n {formatMessage({\n id: getTranslation('plugin.page.form.restore'),\n defaultMessage: 'Restore to default',\n })}\n </Button>\n\n <Button variant=\"default\" type=\"submit\" marginTop={4}>\n {formatMessage({\n id: getTranslation('plugin.page.form.save'),\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </form>\n </Box>\n </Box>\n </Main>\n );\n};\n\nexport { HomePage };\n","import { Page } from '@strapi/strapi/admin';\nimport { Routes, Route } from 'react-router-dom';\n\nimport { HomePage } from './HomePage';\n\nconst App = () => {\n return (\n <Routes>\n <Route index element={<HomePage />} />\n <Route path=\"*\" element={<Page.Error />} />\n </Routes>\n );\n};\n\nexport { App };\n"],"names":[],"mappings":"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"}
@@ -221,3 +221,4 @@ const App = () => {
221
221
  ] });
222
222
  };
223
223
  exports.App = App;
224
+ //# sourceMappingURL=App-COSMdnpL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App-COSMdnpL.js","sources":["../../admin/src/utils/constants.ts","../../admin/src/pages/HomePage.tsx","../../admin/src/pages/App.tsx"],"sourcesContent":["export const DEFAULT_SYSTEM_PROMPT =\n 'You are a professional translator. Your task is to translate the provided content accurately while preserving the original meaning and tone.';\n\nexport const DEFAULT_LLM_TEMPERATURE = 0.3;\n\nexport const MAX_LLM_TEMPERATURE = 2;\nexport const MIN_LLM_TEMPERATURE = 0.1;\n","import {\n Box,\n Button,\n Field,\n Flex,\n Main,\n Typography,\n Textarea,\n TextInput,\n NumberInput,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { useEffect, useState } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\nimport { getTranslation } from '../utils/getTranslation';\nimport { PLUGIN_ID } from '../../src/pluginId';\nimport { PluginConfig } from '../../custom';\nimport { PluginIcon } from '../../src/components/PluginIcon';\nimport {\n DEFAULT_LLM_TEMPERATURE,\n DEFAULT_SYSTEM_PROMPT,\n MAX_LLM_TEMPERATURE,\n MIN_LLM_TEMPERATURE,\n} from '../utils/constants';\n\ninterface FormEvent extends React.FormEvent<HTMLFormElement> {\n preventDefault(): void;\n}\n\nconst HomePage = () => {\n const [config, setConfig] = useState({ systemPrompt: '', temperature: 0.3 });\n const { formatMessage } = useIntl();\n const { get, post } = useFetchClient();\n\n useEffect(() => {\n // Fetch current config\n const fetchData = async () => {\n const response = await get(`/${PLUGIN_ID}/config`);\n setConfig({ ...config, ...response.data });\n };\n fetchData();\n }, []);\n\n const handleSubmit = async (e: FormEvent): Promise<void> => {\n e.preventDefault();\n await post(`/${PLUGIN_ID}/config`, { ...(config as PluginConfig) });\n };\n\n const handleRestore = async (): Promise<void> => {\n setConfig({ systemPrompt: DEFAULT_SYSTEM_PROMPT, temperature: DEFAULT_LLM_TEMPERATURE });\n await post(`/${PLUGIN_ID}/config`, {\n systemPrompt: DEFAULT_SYSTEM_PROMPT,\n temperature: DEFAULT_LLM_TEMPERATURE,\n });\n };\n\n return (\n <Main>\n <Box\n paddingLeft={10}\n paddingRight={10}\n paddingBottom={8}\n paddingTop={8}\n data-strapi-header\n background=\"neutral100\"\n >\n <Flex data-strapi-header alignItems=\"center\" gap={3} marginBottom={4}>\n <PluginIcon width={42} height={42} />{' '}\n <Typography variant=\"alpha\" tag=\"h1\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslation('plugin.page.title'),\n defaultMessage: 'LLM Translator (Configuration)',\n })}\n </Typography>\n </Flex>\n <Typography variant=\"delta\" textColor=\"neutral600\" fontWeight=\"normal\">\n {formatMessage({\n id: getTranslation('plugin.page.description'),\n defaultMessage:\n 'Configure the LLM Translator plugin settings. Be aware that Base Model, API Key and LLM Base URL need to be set as environment variables.',\n })}\n </Typography>\n </Box>\n\n <Box paddingLeft={10} paddingRight={10}>\n <Box\n paddingLeft={10}\n paddingRight={10}\n paddingTop={8}\n paddingBottom={8}\n background=\"neutral0\"\n >\n <form onSubmit={handleSubmit}>\n <Field.Root\n id=\"system_prompt\"\n hint={formatMessage({\n id: getTranslation('plugin.page.form.system_prompt_hint'),\n defaultMessage:\n 'This is (part) of the prompt that will be used to instruct the LLM. It should be clear and concise.',\n })}\n required\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.system_prompt'),\n defaultMessage: 'System prompt',\n })}\n </Field.Label>\n <Textarea\n id=\"system_prompt\"\n value={config.systemPrompt as string}\n onChange={(e: { target: { value: string } }) =>\n setConfig({ ...config, systemPrompt: e.target.value })\n }\n required\n placeholder={DEFAULT_SYSTEM_PROMPT}\n name=\"system_prompt\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Flex gap={4} marginTop={6} flex={1}>\n <Field.Root\n id=\"llm_temperature\"\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_temperature_hint'),\n defaultMessage:\n 'Temperature setting for the LLM. A higher value will make the output more random, while a lower value will make it more focused and deterministic.',\n })}\n flex={1}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_temperature'),\n defaultMessage: 'LLM Temperature',\n })}\n </Field.Label>\n <NumberInput\n id=\"llm_temperature\"\n value={config.temperature}\n name=\"llm_temperature\"\n step={0.1}\n min={MIN_LLM_TEMPERATURE}\n max={MAX_LLM_TEMPERATURE}\n onValueChange={(value: number | undefined) => {\n let tempValue = DEFAULT_LLM_TEMPERATURE;\n if (value === undefined) {\n tempValue = DEFAULT_LLM_TEMPERATURE;\n } else if (value < MIN_LLM_TEMPERATURE) {\n tempValue = MIN_LLM_TEMPERATURE;\n } else if (value > MAX_LLM_TEMPERATURE) {\n tempValue = MAX_LLM_TEMPERATURE;\n } else {\n tempValue = value;\n }\n\n setConfig({ ...config, temperature: tempValue });\n }}\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_model\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_model_hint'),\n defaultMessage:\n 'Model that will be used to generate the translations. It should be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_model'),\n defaultMessage: 'LLM Model',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_model\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL as string}\n disabled\n name=\"llm_model\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n <Field.Root\n id=\"llm_base_url\"\n flex={1}\n hint={formatMessage({\n id: getTranslation('plugin.page.form.llm_base_url_hint'),\n defaultMessage:\n 'Base URL for the LLM API. It needs to be set as an environment variable.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: getTranslation('plugin.page.form.llm_base_url'),\n defaultMessage: 'LLM Base Url',\n })}\n </Field.Label>\n <TextInput\n id=\"llm_base_url\"\n value={process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL as string}\n disabled\n name=\"llm_base_url\"\n />\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n </Flex>\n <Flex gap={2} marginTop={6} justifyContent=\"flex-end\">\n <Button variant=\"secondary\" type=\"button\" onClick={handleRestore} marginTop={4}>\n {formatMessage({\n id: getTranslation('plugin.page.form.restore'),\n defaultMessage: 'Restore to default',\n })}\n </Button>\n\n <Button variant=\"default\" type=\"submit\" marginTop={4}>\n {formatMessage({\n id: getTranslation('plugin.page.form.save'),\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </form>\n </Box>\n </Box>\n </Main>\n );\n};\n\nexport { HomePage };\n","import { Page } from '@strapi/strapi/admin';\nimport { Routes, Route } from 'react-router-dom';\n\nimport { HomePage } from './HomePage';\n\nconst App = () => {\n return (\n <Routes>\n <Route index element={<HomePage />} />\n <Route path=\"*\" element={<Page.Error />} />\n </Routes>\n );\n};\n\nexport { App };\n"],"names":["useState","useIntl","useFetchClient","useEffect","PLUGIN_ID","Main","jsxs","Box","Flex","jsx","PluginIcon","Typography","getTranslation","Field","Textarea","NumberInput","TextInput","Button","Routes","Route","Page"],"mappings":"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"}