strapi-llm-translator 0.9.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 (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/dist/_chunks/App-Boy_i56G.mjs +223 -0
  4. package/dist/_chunks/App-COSMdnpL.js +223 -0
  5. package/dist/_chunks/de-CvAR4QXO.js +29 -0
  6. package/dist/_chunks/de-D3VSS3Mq.mjs +29 -0
  7. package/dist/_chunks/en-BjVvIBv8.js +29 -0
  8. package/dist/_chunks/en-BnBUQVgF.mjs +29 -0
  9. package/dist/_chunks/index-BEhzLY5B.mjs +277 -0
  10. package/dist/_chunks/index-DuLkx3CK.js +276 -0
  11. package/dist/admin/index.js +3 -0
  12. package/dist/admin/index.mjs +4 -0
  13. package/dist/admin/src/components/Initializer.d.ts +5 -0
  14. package/dist/admin/src/components/LLMButton.d.ts +2 -0
  15. package/dist/admin/src/components/PluginIcon.d.ts +18 -0
  16. package/dist/admin/src/index.d.ts +11 -0
  17. package/dist/admin/src/pages/App.d.ts +2 -0
  18. package/dist/admin/src/pages/HomePage.d.ts +2 -0
  19. package/dist/admin/src/pluginId.d.ts +1 -0
  20. package/dist/admin/src/utils/constants.d.ts +4 -0
  21. package/dist/admin/src/utils/getLocaleFromUrl.d.ts +1 -0
  22. package/dist/admin/src/utils/getTranslation.d.ts +2 -0
  23. package/dist/server/index.js +392 -0
  24. package/dist/server/index.mjs +393 -0
  25. package/dist/server/src/bootstrap.d.ts +5 -0
  26. package/dist/server/src/config/constants.d.ts +2 -0
  27. package/dist/server/src/config/index.d.ts +9 -0
  28. package/dist/server/src/content-types/index.d.ts +2 -0
  29. package/dist/server/src/controllers/admin.controller.d.ts +11 -0
  30. package/dist/server/src/controllers/index.d.ts +23 -0
  31. package/dist/server/src/destroy.d.ts +5 -0
  32. package/dist/server/src/index.d.ts +63 -0
  33. package/dist/server/src/middlewares/index.d.ts +2 -0
  34. package/dist/server/src/policies/index.d.ts +2 -0
  35. package/dist/server/src/register.d.ts +5 -0
  36. package/dist/server/src/routes/admin.d.ts +9 -0
  37. package/dist/server/src/routes/index.d.ts +14 -0
  38. package/dist/server/src/services/index.d.ts +6 -0
  39. package/dist/server/src/services/llm-service.d.ts +6 -0
  40. package/dist/server/src/types/controllers.d.ts +22 -0
  41. package/dist/server/src/types/index.d.ts +41 -0
  42. package/package.json +70 -0
@@ -0,0 +1,393 @@
1
+ import { OpenAI } from "openai";
2
+ const bootstrap = ({ strapi: strapi2 }) => {
3
+ };
4
+ const destroy = ({ strapi: strapi2 }) => {
5
+ };
6
+ const register = ({ strapi: strapi2 }) => {
7
+ };
8
+ const config = {
9
+ default: {
10
+ llmApiKey: process.env.LLM_TRANSLATOR_LLM_API_KEY,
11
+ llmEndpoint: process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL || "https://api.openai.com/v1/chat/completions",
12
+ llmModel: process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL || "gpt-4o"
13
+ },
14
+ validator() {
15
+ const {
16
+ LLM_TRANSLATOR_LLM_API_KEY,
17
+ STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL,
18
+ STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL
19
+ } = process.env;
20
+ if (!LLM_TRANSLATOR_LLM_API_KEY) {
21
+ throw new Error("LLM_TRANSLATOR_LLM_API_KEY is required");
22
+ }
23
+ if (!STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL) {
24
+ console.info(
25
+ "STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL is not set, using default: https://api.openai.com/v1/chat/completions"
26
+ );
27
+ } else {
28
+ console.info(
29
+ `STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL is set to: ${STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL}`
30
+ );
31
+ }
32
+ if (!STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL) {
33
+ console.info("STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL is not set, using default: gpt-4o");
34
+ } else {
35
+ console.info(
36
+ `STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL is set to: ${STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL}`
37
+ );
38
+ }
39
+ }
40
+ };
41
+ const contentTypes = {};
42
+ const controllers$1 = ({ strapi: strapi2 }) => ({
43
+ // Genertate translations
44
+ async generate(ctx) {
45
+ try {
46
+ const { fields, components, targetLanguage, contentType } = ctx.request.body;
47
+ const result = await strapi2.plugin("strapi-llm-translator").service("llm-service").generateWithLLM(contentType, fields, components, {
48
+ targetLanguage
49
+ });
50
+ ctx.status = result.meta.status;
51
+ ctx.body = result;
52
+ } catch (error) {
53
+ console.error("Error in generate controller:", error);
54
+ ctx.status = 500;
55
+ ctx.body = {
56
+ meta: {
57
+ ok: false,
58
+ status: 500,
59
+ message: "Internal server error"
60
+ }
61
+ };
62
+ }
63
+ },
64
+ // Get the configuration
65
+ async getConfig(ctx) {
66
+ const pluginStore = strapi2.store({
67
+ environment: strapi2.config.environment,
68
+ type: "plugin",
69
+ name: "strapi-llm-translator"
70
+ // replace with your plugin name
71
+ });
72
+ const config2 = await pluginStore.get({ key: "configuration" });
73
+ ctx.body = config2 || {};
74
+ },
75
+ // Save the configuration
76
+ async setConfig(ctx) {
77
+ const { body } = ctx.request;
78
+ const pluginStore = strapi2.store({
79
+ environment: strapi2.config.environment,
80
+ type: "plugin",
81
+ name: "strapi-llm-translator"
82
+ // replace with your plugin name
83
+ });
84
+ await pluginStore.set({
85
+ key: "configuration",
86
+ value: { ...body }
87
+ });
88
+ ctx.body = await pluginStore.get({ key: "configuration" });
89
+ }
90
+ });
91
+ const controllers = {
92
+ admin: controllers$1
93
+ };
94
+ const middlewares = {};
95
+ const policies = {};
96
+ const adminRoutes = [
97
+ {
98
+ method: "POST",
99
+ path: "/generate",
100
+ handler: "admin.generate",
101
+ config: {
102
+ policies: []
103
+ }
104
+ },
105
+ {
106
+ method: "GET",
107
+ path: "/config",
108
+ handler: "admin.getConfig",
109
+ config: {
110
+ policies: []
111
+ }
112
+ },
113
+ {
114
+ method: "POST",
115
+ path: "/config",
116
+ handler: "admin.setConfig",
117
+ config: {
118
+ policies: []
119
+ }
120
+ }
121
+ ];
122
+ const routes = {
123
+ admin: {
124
+ type: "admin",
125
+ routes: adminRoutes
126
+ }
127
+ };
128
+ 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.";
129
+ const SYSTEM_PROMPT_APPENDIX = `The user asks you to translate the text to a specific language, the language is provided via short code like "en", "fr", "de", etc.`;
130
+ const openai = new OpenAI({
131
+ baseURL: process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_BASE_URL,
132
+ apiKey: process.env.LLM_TRANSLATOR_LLM_API_KEY
133
+ });
134
+ const model = process.env.STRAPI_ADMIN_LLM_TRANSLATOR_LLM_MODEL;
135
+ const isTranslatableField = (contentType, key, value) => {
136
+ if (typeof value !== "string") {
137
+ return false;
138
+ }
139
+ const fieldSchema = contentType?.attributes?.[key];
140
+ if (!fieldSchema) {
141
+ return false;
142
+ }
143
+ const isStringOrText = ["string", "text"].includes(fieldSchema.type);
144
+ const isNotUID = fieldSchema.type !== "uid";
145
+ const isLocalizable = fieldSchema.pluginOptions?.i18n?.localized !== false;
146
+ return isStringOrText && isNotUID && isLocalizable;
147
+ };
148
+ const extractTranslatableFields = (contentType, fields, components = {}) => {
149
+ const translatableFields = [];
150
+ Object.entries(fields).forEach(([key, value]) => {
151
+ if (isTranslatableField(contentType, key, value)) {
152
+ translatableFields.push({
153
+ path: [key],
154
+ value,
155
+ originalPath: [key]
156
+ });
157
+ }
158
+ });
159
+ if (fields.blocks && Array.isArray(fields.blocks)) {
160
+ fields.blocks.forEach((block, blockIndex) => {
161
+ if (block.__component && components[block.__component]) {
162
+ const componentSchema = components[block.__component];
163
+ Object.entries(componentSchema.attributes).forEach(([fieldName, schema]) => {
164
+ if (block[fieldName] && typeof block[fieldName] === "string" && ["string", "text", "richtext"].includes(schema.type)) {
165
+ translatableFields.push({
166
+ path: ["blocks", String(blockIndex), fieldName],
167
+ value: block[fieldName],
168
+ originalPath: ["blocks", String(blockIndex), fieldName]
169
+ });
170
+ }
171
+ });
172
+ }
173
+ });
174
+ }
175
+ return translatableFields;
176
+ };
177
+ const prepareTranslationPayload = (fields) => {
178
+ const payload = {};
179
+ fields.forEach((field) => {
180
+ let current = payload;
181
+ field.path.forEach((part, index2) => {
182
+ if (index2 === field.path.length - 1) {
183
+ current[part] = field.value;
184
+ } else {
185
+ current[part] = current[part] || {};
186
+ current = current[part];
187
+ }
188
+ });
189
+ });
190
+ return payload;
191
+ };
192
+ const mergeTranslatedContent = (originalData, translatedData, translatableFields) => {
193
+ const result = JSON.parse(JSON.stringify(originalData));
194
+ translatableFields.forEach((field) => {
195
+ let translatedValue = translatedData;
196
+ for (const part of field.path) {
197
+ translatedValue = translatedValue?.[part];
198
+ if (translatedValue === void 0) break;
199
+ }
200
+ if (translatedValue !== void 0) {
201
+ let current = result;
202
+ field.originalPath.forEach((part, index2) => {
203
+ if (index2 === field.originalPath.length - 1) {
204
+ current[part] = translatedValue;
205
+ } else {
206
+ current = current[part];
207
+ }
208
+ });
209
+ }
210
+ });
211
+ return result;
212
+ };
213
+ const generateSlug = async (data, field, contentTypeUID) => {
214
+ const uidService = strapi.service("plugin::content-manager.uid");
215
+ const slug = await uidService.generateUIDField({
216
+ contentTypeUID,
217
+ field,
218
+ data
219
+ });
220
+ return slug;
221
+ };
222
+ const findUIDFields = (contentType) => {
223
+ const uidFields = [];
224
+ Object.entries(contentType.attributes || {}).forEach(([fieldName, schema]) => {
225
+ if (schema.type === "uid" && schema.targetField) {
226
+ uidFields.push({
227
+ fieldName,
228
+ targetField: schema.targetField
229
+ });
230
+ }
231
+ });
232
+ return uidFields;
233
+ };
234
+ const generateUIDsForTranslatedFields = async (uidFields, translatedData, contentTypeUID, mergedContent) => {
235
+ const translatedUIDs = {};
236
+ for (const { fieldName, targetField } of uidFields) {
237
+ if (translatedData[targetField] !== void 0) {
238
+ try {
239
+ const newUID = await generateSlug(
240
+ {
241
+ ...mergedContent,
242
+ [targetField]: translatedData[targetField]
243
+ },
244
+ fieldName,
245
+ contentTypeUID
246
+ );
247
+ translatedUIDs[fieldName] = newUID;
248
+ } catch (error) {
249
+ console.error(`Failed to generate UID for field ${fieldName}:`, error);
250
+ }
251
+ }
252
+ }
253
+ return translatedUIDs;
254
+ };
255
+ const llmService = ({ strapi: strapi2 }) => ({
256
+ async generateWithLLM(contentType, fields, components, config2) {
257
+ try {
258
+ const userConfig = await getUserConfig();
259
+ const translatableFields = extractTranslatableFields(contentType, fields, components);
260
+ const translationPayload = prepareTranslationPayload(translatableFields);
261
+ const prompt = buildPrompt(translationPayload, config2.targetLanguage);
262
+ const systemPrompt = await buildSystemPrompt(userConfig);
263
+ const response = await callLLMProvider(prompt, systemPrompt, model, userConfig);
264
+ const translatedData = parseLLMResponse(response);
265
+ const mergedContent = mergeTranslatedContent(fields, translatedData, translatableFields);
266
+ const uidFields = findUIDFields(contentType);
267
+ const translatedUIDs = await generateUIDsForTranslatedFields(
268
+ uidFields,
269
+ translatedData,
270
+ contentType.uid,
271
+ mergedContent
272
+ );
273
+ return {
274
+ data: {
275
+ ...mergedContent,
276
+ ...translatedUIDs
277
+ },
278
+ meta: {
279
+ ok: true,
280
+ status: 200,
281
+ message: "Translation completed successfully"
282
+ }
283
+ };
284
+ } catch (error) {
285
+ strapi2.log.error("LLM translation error:", error);
286
+ return {
287
+ data: fields,
288
+ // Return original fields in case of error
289
+ meta: {
290
+ ok: false,
291
+ status: 500,
292
+ message: error instanceof Error ? error.message : "Translation failed"
293
+ }
294
+ };
295
+ }
296
+ }
297
+ });
298
+ const buildPrompt = (fields, targetLanguage) => {
299
+ return `You are translating content from a CMS. Please translate the following JSON data to ${targetLanguage}.
300
+
301
+ IMPORTANT RULES:
302
+ 1. Preserve all JSON structure and keys exactly as provided
303
+ 2. Only translate string values
304
+ 3. Maintain any markdown formatting within the text
305
+ 4. Keep HTML tags intact if present
306
+ 5. Preserve any special characters or placeholders
307
+ 6. Return ONLY the translated JSON object
308
+ 7. Do not add any explanations or comments
309
+ 8. Ensure professional and culturally appropriate translations
310
+
311
+ SOURCE JSON:
312
+ ${JSON.stringify(fields, null, 2)}`;
313
+ };
314
+ const getUserConfig = async () => {
315
+ const pluginStore = strapi.store({
316
+ environment: strapi.config.environment,
317
+ type: "plugin",
318
+ name: "strapi-llm-translator"
319
+ });
320
+ const config2 = await pluginStore.get({ key: "configuration" });
321
+ return config2;
322
+ };
323
+ const buildSystemPrompt = async (config2) => {
324
+ return `${config2.systemPrompt || DEFAULT_SYSTEM_PROMPT} ${SYSTEM_PROMPT_APPENDIX}`;
325
+ };
326
+ const callLLMProvider = async (prompt, systemPrompt, model2, config2) => {
327
+ const response = await openai.chat.completions.create({
328
+ model: model2,
329
+ messages: [
330
+ {
331
+ role: "system",
332
+ content: systemPrompt
333
+ },
334
+ {
335
+ role: "user",
336
+ content: prompt
337
+ }
338
+ ],
339
+ temperature: config2.temperature
340
+ });
341
+ return response;
342
+ };
343
+ const parseLLMResponse = (response) => {
344
+ try {
345
+ const content = response.choices[0]?.message?.content;
346
+ if (!content) throw new Error("No content in response");
347
+ const cleanContent = content.replace(/^```json\s*\n/, "").replace(/^```\s*\n/, "").replace(/\n\s*```$/, "").replace(/\u200B/g, "").replace(/[\u2018\u2019]/g, "'").replace(/[\u201C\u201D]/g, '"').trim();
348
+ try {
349
+ const parsed = JSON.parse(cleanContent);
350
+ if (typeof parsed === "object" && parsed !== null) {
351
+ return parsed;
352
+ }
353
+ throw new Error("Invalid response format - not an object");
354
+ } catch (parseError) {
355
+ const openBraces = (cleanContent.match(/{/g) || []).length;
356
+ const closeBraces = (cleanContent.match(/}/g) || []).length;
357
+ if (openBraces > closeBraces) {
358
+ const missingBraces = openBraces - closeBraces;
359
+ const fixedContent = cleanContent + "}".repeat(missingBraces);
360
+ try {
361
+ const parsed = JSON.parse(fixedContent);
362
+ if (typeof parsed === "object" && parsed !== null) {
363
+ return parsed;
364
+ }
365
+ } catch (secondError) {
366
+ console.error("Second parse attempt failed:", secondError);
367
+ }
368
+ }
369
+ throw new Error(`JSON parsing failed: ${parseError.message}`);
370
+ }
371
+ } catch (error) {
372
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
373
+ throw new Error(`Translation failed: ${errorMessage}`);
374
+ }
375
+ };
376
+ const services = {
377
+ "llm-service": llmService
378
+ };
379
+ const index = {
380
+ register,
381
+ bootstrap,
382
+ destroy,
383
+ config,
384
+ controllers,
385
+ routes,
386
+ services,
387
+ contentTypes,
388
+ policies,
389
+ middlewares
390
+ };
391
+ export {
392
+ index as default
393
+ };
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const bootstrap: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default bootstrap;
@@ -0,0 +1,2 @@
1
+ export declare 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.";
2
+ export declare const SYSTEM_PROMPT_APPENDIX = "The user asks you to translate the text to a specific language, the language is provided via short code like \"en\", \"fr\", \"de\", etc.";
@@ -0,0 +1,9 @@
1
+ declare const _default: {
2
+ default: {
3
+ llmApiKey: string;
4
+ llmEndpoint: string;
5
+ llmModel: string;
6
+ };
7
+ validator(): void;
8
+ };
9
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { RequestContext, StrapiContext, GenerateRequestBody } from 'src/types';
2
+ declare const controllers: ({ strapi }: StrapiContext) => {
3
+ generate(ctx: RequestContext & {
4
+ request: {
5
+ body: GenerateRequestBody;
6
+ };
7
+ }): Promise<void>;
8
+ getConfig(ctx: RequestContext): Promise<void>;
9
+ setConfig(ctx: RequestContext): Promise<void>;
10
+ };
11
+ export default controllers;
@@ -0,0 +1,23 @@
1
+ /// <reference types="koa" />
2
+ declare const _default: {
3
+ admin: ({ strapi }: import("../types").StrapiContext) => {
4
+ generate(ctx: Omit<import("koa").Context, "body" | "query" | "request"> & {
5
+ body: object;
6
+ query: object;
7
+ params: object;
8
+ request: Omit<import("koa").Request, "body"> & {
9
+ body: object;
10
+ };
11
+ state: {
12
+ user?: import("../types").AdminUser;
13
+ };
14
+ } & {
15
+ request: {
16
+ body: import("../types").GenerateRequestBody;
17
+ };
18
+ }): Promise<void>;
19
+ getConfig(ctx: import("../types").RequestContext): Promise<void>;
20
+ setConfig(ctx: import("../types").RequestContext): Promise<void>;
21
+ };
22
+ };
23
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const destroy: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default destroy;
@@ -0,0 +1,63 @@
1
+ /// <reference types="koa" />
2
+ declare const _default: {
3
+ register: ({ strapi }: {
4
+ strapi: import("@strapi/types/dist/core").Strapi;
5
+ }) => void;
6
+ bootstrap: ({ strapi }: {
7
+ strapi: import("@strapi/types/dist/core").Strapi;
8
+ }) => void;
9
+ destroy: ({ strapi }: {
10
+ strapi: import("@strapi/types/dist/core").Strapi;
11
+ }) => void;
12
+ config: {
13
+ default: {
14
+ llmApiKey: string;
15
+ llmEndpoint: string;
16
+ llmModel: string;
17
+ };
18
+ validator(): void;
19
+ };
20
+ controllers: {
21
+ admin: ({ strapi }: import("./types").StrapiContext) => {
22
+ generate(ctx: Omit<import("koa").Context, "body" | "query" | "request"> & {
23
+ body: object;
24
+ query: object;
25
+ params: object;
26
+ request: Omit<import("koa").Request, "body"> & {
27
+ body: object;
28
+ };
29
+ state: {
30
+ user?: import("./types").AdminUser;
31
+ };
32
+ } & {
33
+ request: {
34
+ body: import("./types").GenerateRequestBody;
35
+ };
36
+ }): Promise<void>;
37
+ getConfig(ctx: import("./types").RequestContext): Promise<void>;
38
+ setConfig(ctx: import("./types").RequestContext): Promise<void>;
39
+ };
40
+ };
41
+ routes: {
42
+ admin: {
43
+ type: string;
44
+ routes: {
45
+ method: string;
46
+ path: string;
47
+ handler: string;
48
+ config: {
49
+ policies: any[];
50
+ };
51
+ }[];
52
+ };
53
+ };
54
+ services: {
55
+ 'llm-service': ({ strapi }: {
56
+ strapi: import("@strapi/types/dist/core").Strapi;
57
+ }) => import("./types").LLMServiceType;
58
+ };
59
+ contentTypes: {};
60
+ policies: {};
61
+ middlewares: {};
62
+ };
63
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: {};
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const register: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default register;
@@ -0,0 +1,9 @@
1
+ declare const _default: {
2
+ method: string;
3
+ path: string;
4
+ handler: string;
5
+ config: {
6
+ policies: any[];
7
+ };
8
+ }[];
9
+ export default _default;
@@ -0,0 +1,14 @@
1
+ declare const routes: {
2
+ admin: {
3
+ type: string;
4
+ routes: {
5
+ method: string;
6
+ path: string;
7
+ handler: string;
8
+ config: {
9
+ policies: any[];
10
+ };
11
+ }[];
12
+ };
13
+ };
14
+ export default routes;
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ 'llm-service': ({ strapi }: {
3
+ strapi: import("@strapi/types/dist/core").Strapi;
4
+ }) => import("../types").LLMServiceType;
5
+ };
6
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ import { LLMServiceType } from '../../src/types';
3
+ declare const llmService: ({ strapi }: {
4
+ strapi: Core.Strapi;
5
+ }) => LLMServiceType;
6
+ export default llmService;
@@ -0,0 +1,22 @@
1
+ import { Context } from 'koa';
2
+ export type AdminUser = {
3
+ id: string | number;
4
+ email: string;
5
+ username: string;
6
+ avatar?: string;
7
+ };
8
+ export type RequestContext<Body = object, PathParams = object, QueryParams = object> = Omit<Context, 'body' | 'query' | 'request'> & {
9
+ body: Body;
10
+ query: QueryParams;
11
+ params: PathParams;
12
+ request: Omit<Context['request'], 'body'> & {
13
+ body: Body;
14
+ };
15
+ state: {
16
+ user?: AdminUser;
17
+ };
18
+ };
19
+ export interface PluginConfig {
20
+ systemPrompt: string;
21
+ temperature: number;
22
+ }
@@ -0,0 +1,41 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ export * from './controllers';
3
+ export type CoreStrapi = Omit<Core.Strapi, 'query' | 'plugin'> & {
4
+ plugin: (pluginName: string) => Omit<Core.Plugin, 'contentTypes'> & {
5
+ contentTypes: Record<string, Core.Plugin['contentTypes'][string] & {
6
+ uid: string;
7
+ }>;
8
+ };
9
+ };
10
+ export type StrapiContext = {
11
+ readonly strapi: CoreStrapi;
12
+ };
13
+ export interface TranslationResponse {
14
+ data: Record<string, any>;
15
+ meta: {
16
+ ok: boolean;
17
+ status: number;
18
+ message?: string;
19
+ };
20
+ }
21
+ export interface TranslationConfig {
22
+ targetLanguage: string;
23
+ }
24
+ export interface LLMServiceType {
25
+ generateWithLLM(contentType: Record<string, any>, fields: Record<string, any>, components: Record<string, any>, config: TranslationConfig): Promise<Record<string, any>>;
26
+ }
27
+ export interface GenerateRequestBody {
28
+ contentType: string;
29
+ fields: any;
30
+ components: any;
31
+ targetLanguage: string;
32
+ }
33
+ export interface TranslatableField {
34
+ path: string[];
35
+ value: string;
36
+ originalPath: string[];
37
+ }
38
+ export interface UIDField {
39
+ fieldName: string;
40
+ targetField: string;
41
+ }