@intlayer/backend 7.2.3 → 7.3.0-canary.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 +2 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/blog/en/compiler_vs_declarative_i18n.json +5132 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/build.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/configuration.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/debug.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/doc-review.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/doc-translate.json +3080 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/editor.json +1028 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/fill.json +3080 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/index.json +4106 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/list.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/live.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/pull.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/push.json +3080 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/sdk.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/test.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/transform.json +2054 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/version.json +1028 -0
- package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/watch.json +1028 -0
- package/dist/esm/controllers/ai.controller.mjs +23 -23
- package/dist/esm/controllers/ai.controller.mjs.map +1 -1
- package/dist/esm/export.mjs +3 -2
- package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs +1 -1
- package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -1
- package/dist/esm/utils/AI/askDocQuestion/indexMarkdownFiles.mjs.map +1 -1
- package/dist/esm/utils/AI/auditDictionary/index.mjs +1 -1
- package/dist/esm/utils/AI/auditDictionary/index.mjs.map +1 -1
- package/dist/esm/utils/AI/auditDictionaryField/index.mjs +1 -1
- package/dist/esm/utils/AI/auditDictionaryField/index.mjs.map +1 -1
- package/dist/esm/utils/AI/auditDictionaryMetadata/index.mjs +5 -29
- package/dist/esm/utils/AI/auditDictionaryMetadata/index.mjs.map +1 -1
- package/dist/esm/utils/AI/auditTag/index.mjs +1 -1
- package/dist/esm/utils/AI/auditTag/index.mjs.map +1 -1
- package/dist/esm/utils/AI/autocomplete/index.mjs +1 -2
- package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -1
- package/dist/esm/utils/AI/customQuery/index.mjs +5 -11
- package/dist/esm/utils/AI/customQuery/index.mjs.map +1 -1
- package/dist/esm/utils/AI/translateJSON/index.mjs +6 -53
- package/dist/esm/utils/AI/translateJSON/index.mjs.map +1 -1
- package/dist/types/controllers/ai.controller.d.ts +1 -1
- package/dist/types/controllers/ai.controller.d.ts.map +1 -1
- package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
- package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
- package/dist/types/emails/InviteUserEmail.d.ts +4 -4
- package/dist/types/emails/MagicLinkEmail.d.ts +4 -4
- package/dist/types/emails/OAuthTokenCreatedEmail.d.ts +4 -4
- package/dist/types/emails/PasswordChangeConfirmation.d.ts +4 -4
- package/dist/types/emails/PasswordChangeConfirmation.d.ts.map +1 -1
- package/dist/types/emails/ResetUserPassword.d.ts +4 -4
- package/dist/types/emails/ResetUserPassword.d.ts.map +1 -1
- package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +4 -4
- package/dist/types/emails/SubscriptionPaymentError.d.ts +4 -4
- package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +4 -4
- package/dist/types/emails/ValidateUserEmail.d.ts +4 -4
- package/dist/types/emails/Welcome.d.ts +4 -4
- package/dist/types/export.d.ts +2 -2
- package/dist/types/models/dictionary.model.d.ts +4 -4
- package/dist/types/models/dictionary.model.d.ts.map +1 -1
- package/dist/types/models/discussion.model.d.ts +2 -2
- package/dist/types/models/discussion.model.d.ts.map +1 -1
- package/dist/types/models/oAuth2.model.d.ts +3 -3
- package/dist/types/models/oAuth2.model.d.ts.map +1 -1
- package/dist/types/schemas/dictionary.schema.d.ts +6 -6
- package/dist/types/schemas/discussion.schema.d.ts +6 -6
- package/dist/types/schemas/oAuth2.schema.d.ts +5 -5
- package/dist/types/schemas/organization.schema.d.ts +6 -6
- package/dist/types/schemas/plans.schema.d.ts +6 -6
- package/dist/types/schemas/project.schema.d.ts +6 -6
- package/dist/types/schemas/project.schema.d.ts.map +1 -1
- package/dist/types/schemas/session.schema.d.ts +6 -6
- package/dist/types/schemas/tag.schema.d.ts +6 -6
- package/dist/types/schemas/tag.schema.d.ts.map +1 -1
- package/dist/types/schemas/user.schema.d.ts +6 -6
- package/dist/types/services/email.service.d.ts +11 -11
- package/dist/types/types/plan.types.d.ts.map +1 -1
- package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts +1 -1
- package/dist/types/utils/AI/askDocQuestion/indexMarkdownFiles.d.ts.map +1 -1
- package/dist/types/utils/AI/auditDictionary/index.d.ts +1 -1
- package/dist/types/utils/AI/auditDictionaryField/index.d.ts +1 -1
- package/dist/types/utils/AI/auditDictionaryMetadata/index.d.ts +3 -16
- package/dist/types/utils/AI/auditDictionaryMetadata/index.d.ts.map +1 -1
- package/dist/types/utils/AI/auditTag/index.d.ts +1 -1
- package/dist/types/utils/AI/autocomplete/index.d.ts +1 -1
- package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -1
- package/dist/types/utils/AI/customQuery/index.d.ts +3 -10
- package/dist/types/utils/AI/customQuery/index.d.ts.map +1 -1
- package/dist/types/utils/AI/translateJSON/index.d.ts +3 -17
- package/dist/types/utils/AI/translateJSON/index.d.ts.map +1 -1
- package/dist/types/utils/filtersAndPagination/getDiscussionFiltersAndPagination.d.ts +2 -2
- package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts +2 -2
- package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts +2 -2
- package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +2 -2
- package/package.json +9 -14
- package/dist/assets/utils/AI/auditDictionaryMetadata/PROMPT.md +0 -73
- package/dist/assets/utils/AI/translateJSON/PROMPT.md +0 -45
- package/dist/esm/utils/AI/aiSdk.mjs +0 -98
- package/dist/esm/utils/AI/aiSdk.mjs.map +0 -1
- package/dist/types/utils/AI/aiSdk.d.ts +0 -62
- package/dist/types/utils/AI/aiSdk.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Organization } from "../../types/organization.types.js";
|
|
2
2
|
import { ResponseWithSession } from "../../middlewares/sessionAuth.middleware.js";
|
|
3
3
|
import { FiltersAndPagination } from "./getFiltersAndPaginationFromBody.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as mongoose104 from "mongoose";
|
|
5
5
|
import { RootFilterQuery } from "mongoose";
|
|
6
6
|
import { Request } from "express";
|
|
7
7
|
|
|
@@ -37,7 +37,7 @@ declare const getOrganizationFiltersAndPagination: (req: Request<FiltersAndPagin
|
|
|
37
37
|
skip: number;
|
|
38
38
|
pageSize: number;
|
|
39
39
|
getNumberOfPages: (totalItems: number) => number;
|
|
40
|
-
filters:
|
|
40
|
+
filters: mongoose104.FilterQuery<Organization>;
|
|
41
41
|
sortOptions: Record<string, 1 | -1>;
|
|
42
42
|
};
|
|
43
43
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Project } from "../../types/project.types.js";
|
|
2
2
|
import { ResponseWithSession } from "../../middlewares/sessionAuth.middleware.js";
|
|
3
3
|
import { FiltersAndPagination } from "./getFiltersAndPaginationFromBody.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as mongoose109 from "mongoose";
|
|
5
5
|
import { RootFilterQuery } from "mongoose";
|
|
6
6
|
import { Request } from "express";
|
|
7
7
|
|
|
@@ -30,7 +30,7 @@ declare const getProjectFiltersAndPagination: (req: Request<FiltersAndPagination
|
|
|
30
30
|
skip: number;
|
|
31
31
|
pageSize: number;
|
|
32
32
|
getNumberOfPages: (totalItems: number) => number;
|
|
33
|
-
filters:
|
|
33
|
+
filters: mongoose109.FilterQuery<Project>;
|
|
34
34
|
sortOptions: Record<string, 1 | -1>;
|
|
35
35
|
};
|
|
36
36
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Tag } from "../../types/tag.types.js";
|
|
2
2
|
import { ResponseWithSession } from "../../middlewares/sessionAuth.middleware.js";
|
|
3
3
|
import { FiltersAndPagination } from "./getFiltersAndPaginationFromBody.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as mongoose105 from "mongoose";
|
|
5
5
|
import { RootFilterQuery } from "mongoose";
|
|
6
6
|
import { Request } from "express";
|
|
7
7
|
|
|
@@ -28,7 +28,7 @@ declare const getTagFiltersAndPagination: (req: Request<FiltersAndPagination<Tag
|
|
|
28
28
|
skip: number;
|
|
29
29
|
pageSize: number;
|
|
30
30
|
getNumberOfPages: (totalItems: number) => number;
|
|
31
|
-
filters:
|
|
31
|
+
filters: mongoose105.FilterQuery<Tag>;
|
|
32
32
|
sortOptions: Record<string, 1 | -1>;
|
|
33
33
|
};
|
|
34
34
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/backend",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.3.0-canary.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Intlayer Backend is a an application that allow you to manage your Intlayer content and interact with the intlayer editor.",
|
|
6
6
|
"keywords": [
|
|
@@ -73,13 +73,8 @@
|
|
|
73
73
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@ai
|
|
77
|
-
"@ai-sdk/deepseek": "1.0.29",
|
|
78
|
-
"@ai-sdk/google": "2.0.40",
|
|
79
|
-
"@ai-sdk/mistral": "2.0.24",
|
|
80
|
-
"@ai-sdk/openai": "2.0.71",
|
|
76
|
+
"@intlayer/ai": "7.3.0-canary.0",
|
|
81
77
|
"@react-email/components": "1.0.1",
|
|
82
|
-
"ai": "5.0.98",
|
|
83
78
|
"better-auth": "1.3.34",
|
|
84
79
|
"compression": "1.8.1",
|
|
85
80
|
"cookie-parser": "1.4.7",
|
|
@@ -87,7 +82,7 @@
|
|
|
87
82
|
"cross-env": "10.1.0",
|
|
88
83
|
"dotenv": "16.6.1",
|
|
89
84
|
"express": "5.1.0",
|
|
90
|
-
"express-intlayer": "7.
|
|
85
|
+
"express-intlayer": "7.3.0-canary.0",
|
|
91
86
|
"express-rate-limit": "8.2.1",
|
|
92
87
|
"helmet": "8.1.0",
|
|
93
88
|
"mongodb": "6.21.0",
|
|
@@ -102,10 +97,10 @@
|
|
|
102
97
|
"winston": "3.18.3"
|
|
103
98
|
},
|
|
104
99
|
"devDependencies": {
|
|
105
|
-
"@intlayer/config": "7.
|
|
106
|
-
"@intlayer/core": "7.
|
|
107
|
-
"@intlayer/docs": "7.
|
|
108
|
-
"@intlayer/types": "7.
|
|
100
|
+
"@intlayer/config": "7.3.0-canary.0",
|
|
101
|
+
"@intlayer/core": "7.3.0-canary.0",
|
|
102
|
+
"@intlayer/docs": "7.3.0-canary.0",
|
|
103
|
+
"@intlayer/types": "7.3.0-canary.0",
|
|
109
104
|
"@types/body-parser": "1.19.6",
|
|
110
105
|
"@types/compression": "1.8.1",
|
|
111
106
|
"@types/cookie-parser": "1.4.10",
|
|
@@ -120,12 +115,12 @@
|
|
|
120
115
|
"@utils/ts-config": "1.0.4",
|
|
121
116
|
"@utils/ts-config-types": "1.0.4",
|
|
122
117
|
"@utils/tsdown-config": "1.0.4",
|
|
123
|
-
"intlayer": "7.
|
|
118
|
+
"intlayer": "7.3.0-canary.0",
|
|
124
119
|
"npm-run-all": "^4.1.5",
|
|
125
120
|
"rimraf": "6.1.2",
|
|
126
121
|
"tsdown": "0.16.6",
|
|
127
122
|
"tsx": "^4.20.6",
|
|
128
123
|
"typescript": "5.9.3",
|
|
129
|
-
"vitest": "4.0.
|
|
124
|
+
"vitest": "4.0.13"
|
|
130
125
|
}
|
|
131
126
|
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
Your role is to describe a content declaration.
|
|
2
|
-
|
|
3
|
-
1. **Terminology:**
|
|
4
|
-
|
|
5
|
-
- **Dictionary:** A content declaration is a is a file (.ts, .js or .json) that contains the multilingual declaration related to a specific content. A content declaration file is usually related to a specific component, or page or section of a website.
|
|
6
|
-
- **Tag:** A tag is attached to a content declaration and is used to group content declaration and harmonize them.
|
|
7
|
-
|
|
8
|
-
2. **Audit Requirements:**
|
|
9
|
-
- **Do Not Alter Structure:** If the file structure is correct, do not modify it. Only add, update, or remove content declarations as necessary.
|
|
10
|
-
- **Misspelled Content:** If declared, detect each `title`, `description` and `tags` are not misspelled. If some content is misspelled, correct it.
|
|
11
|
-
|
|
12
|
-
3. **Fields functions:**
|
|
13
|
-
|
|
14
|
-
- **Title:** The title of the content declaration allows to easily identify it. It should be considered as a readable way to represent the `key` (example: `page-metadata` -> `Page metadata`). It should be a short and descriptive title that accurately reflects the dictionary.
|
|
15
|
-
- **Description:** The description of the content declaration provides a brief summary of the content declaration. It should be a concise and informative description that explains the purpose and content of the dictionary.
|
|
16
|
-
- **Tags:** The tags is an array of strings that represent the key of the tags associated with the content declaration.
|
|
17
|
-
|
|
18
|
-
**Expected Response:**
|
|
19
|
-
|
|
20
|
-
After completion, provide only the final title, description and tags fields in a JSON without any Markdown, code block formatting or any additional comments or explanations.
|
|
21
|
-
|
|
22
|
-
Correct this fields if they are misspelled or do not match the expected content, and / or complete missing title / description / tags.
|
|
23
|
-
|
|
24
|
-
**Example of expected response:**
|
|
25
|
-
|
|
26
|
-
The following case is just an example of expected behavior:
|
|
27
|
-
|
|
28
|
-
- Example of entry:
|
|
29
|
-
|
|
30
|
-
```ts
|
|
31
|
-
import { t, type Dictionary } from "intlayer";
|
|
32
|
-
import { Metadata } from "next";
|
|
33
|
-
|
|
34
|
-
const metadataContent = {
|
|
35
|
-
key: "pricing-metadata",
|
|
36
|
-
title: "",
|
|
37
|
-
description:
|
|
38
|
-
"here a description that doesn't make any sense and should be replaced",
|
|
39
|
-
content: {
|
|
40
|
-
title: t({
|
|
41
|
-
en: "Pricing | Intlayer",
|
|
42
|
-
}),
|
|
43
|
-
description: t({
|
|
44
|
-
en: "Discover our pricing plans and get access to premium features with Intlayer. Choose the plan that suits you best.",
|
|
45
|
-
}),
|
|
46
|
-
keywords: t<string[]>({
|
|
47
|
-
en: ["Pricing", "Subscription"],
|
|
48
|
-
}),
|
|
49
|
-
},
|
|
50
|
-
} satisfies Dictionary<Metadata>;
|
|
51
|
-
|
|
52
|
-
export default metadataContent;
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
- Example of response:
|
|
56
|
-
|
|
57
|
-
```json
|
|
58
|
-
{
|
|
59
|
-
"title": "Pricing page metadata",
|
|
60
|
-
"description": "Metadata related to the pricing page, includes title, description, keywords, metadata for SEO purpose. It will help search engines understand the content of the page.",
|
|
61
|
-
"tags": ["page metadata", "pricing page"]
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**Application Context**
|
|
66
|
-
|
|
67
|
-
{{applicationContext}}
|
|
68
|
-
|
|
69
|
-
**List of existing Tags:**
|
|
70
|
-
|
|
71
|
-
Here the list of existing tags as a context to help you to pick related ones.
|
|
72
|
-
|
|
73
|
-
{{tags}}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
You are an expert in internationalization, copy writing and content management. Your task is to audit the content declaration files in the project and identify any potential issues or inconsistencies. Provide a detailed report of any issues found, including the file path, line number, and a brief explanation of the issue.
|
|
2
|
-
|
|
3
|
-
**Instructions:**
|
|
4
|
-
|
|
5
|
-
2. **Audit Requirements:**
|
|
6
|
-
- **Consistency:** The dictionary format should be the same as the one provided in entry. You should not rename or translate the entry keys.
|
|
7
|
-
- **Missing Content:** Identify any missing translations and specify the expected content.
|
|
8
|
-
- **Misplaced Content:** Detect if any translations are placed under incorrect keys.
|
|
9
|
-
- **Type Compliance:** Verify that the content types match the declarations (e.g., strings, string arrays).
|
|
10
|
-
|
|
11
|
-
3. **Modification Guidelines:**
|
|
12
|
-
- **Do Not Alter Structure:** If the file structure is correct, do not modify it. Only add, update, or remove content declarations as necessary.
|
|
13
|
-
- **Missing Content:** If one key is missing from the Preset Output Content, or if the Preset Output Content is empty, the output content should be completed by translating the Entry Content to Translate into the output locale.
|
|
14
|
-
- **Return Only Final File Content:** Provide the updated file content without any additional comments or explanations.
|
|
15
|
-
- **Manage Localizations:** If the output languages targeted is a variant contains similar languages, as `en` and `en-GB`, consider `en` as English US, and adapt it into `en-GB` as English UK.
|
|
16
|
-
- **Escape Special Characters:** If the translations contain special characters, escape them using the appropriate escape sequence.
|
|
17
|
-
- **Respect the tags and description instructions:** If the tags and description instructions are provided, ensure that the audited file adheres to them.
|
|
18
|
-
- **Consider the Preset Output Content** If Preset Output Content is provided, and coherent with the entry, you can consider reuse it to fill the output file content.
|
|
19
|
-
- **TypeNode field should not be translated** A value as `{ 'nodeType': 'XXX', ...}` should not be translated.
|
|
20
|
-
|
|
21
|
-
**Application Context**
|
|
22
|
-
|
|
23
|
-
{{applicationContext}}
|
|
24
|
-
|
|
25
|
-
**Mode Instruction:**
|
|
26
|
-
|
|
27
|
-
{{modeInstructions}}
|
|
28
|
-
|
|
29
|
-
**Tags Instructions:**
|
|
30
|
-
|
|
31
|
-
{{tagsInstructions}}
|
|
32
|
-
|
|
33
|
-
**Dictionary Description:**
|
|
34
|
-
|
|
35
|
-
{{dictionaryDescription}}
|
|
36
|
-
|
|
37
|
-
**Preset Output Content:**
|
|
38
|
-
|
|
39
|
-
- Target Language: {{outputLocale}}
|
|
40
|
-
|
|
41
|
-
{{presetOutputContent}}
|
|
42
|
-
|
|
43
|
-
**Expected Response:**
|
|
44
|
-
|
|
45
|
-
After auditing, provide only the final content of the file as plain text without any Markdown or code block formatting. If no changes are needed, return the file content exactly as it is.
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2
|
-
import { createDeepSeek } from "@ai-sdk/deepseek";
|
|
3
|
-
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
4
|
-
import { createMistral } from "@ai-sdk/mistral";
|
|
5
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
6
|
-
|
|
7
|
-
//#region src/utils/AI/aiSdk.ts
|
|
8
|
-
/**
|
|
9
|
-
* Supported AI SDK providers
|
|
10
|
-
*/
|
|
11
|
-
let AIProvider = /* @__PURE__ */ function(AIProvider$1) {
|
|
12
|
-
AIProvider$1["OPENAI"] = "openai";
|
|
13
|
-
AIProvider$1["ANTHROPIC"] = "anthropic";
|
|
14
|
-
AIProvider$1["MISTRAL"] = "mistral";
|
|
15
|
-
AIProvider$1["DEEPSEEK"] = "deepseek";
|
|
16
|
-
AIProvider$1["GEMINI"] = "gemini";
|
|
17
|
-
return AIProvider$1;
|
|
18
|
-
}({});
|
|
19
|
-
const getAPIKey = (res, accessType, aiOptions) => {
|
|
20
|
-
const defaultApiKey = process.env.OPENAI_API_KEY;
|
|
21
|
-
if (accessType.includes("public")) return aiOptions?.apiKey ?? defaultApiKey;
|
|
22
|
-
if (accessType.includes("apiKey") && aiOptions?.apiKey) return aiOptions?.apiKey;
|
|
23
|
-
if (accessType.includes("registered_user") && res.locals.user) return aiOptions?.apiKey ?? defaultApiKey;
|
|
24
|
-
if (accessType.includes("premium_user") && res.locals.user) return aiOptions?.apiKey ?? defaultApiKey;
|
|
25
|
-
};
|
|
26
|
-
const getModel = (provider, userApiKey, userModel, defaultModel = "gpt-5-mini") => {
|
|
27
|
-
if (userApiKey) {
|
|
28
|
-
if (provider && provider === AIProvider.OPENAI) return userModel ?? defaultModel;
|
|
29
|
-
switch (provider) {
|
|
30
|
-
case AIProvider.ANTHROPIC: return "claude-sonnet-4-5-20250929";
|
|
31
|
-
case AIProvider.MISTRAL: return "mistral-large-latest";
|
|
32
|
-
case AIProvider.DEEPSEEK: return "deepseek-coder";
|
|
33
|
-
case AIProvider.GEMINI: return "gemini-2.5-flash";
|
|
34
|
-
default: return defaultModel;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (userModel || provider) throw new Error("The user should use his own API key to use a custom model");
|
|
38
|
-
return defaultModel;
|
|
39
|
-
};
|
|
40
|
-
const DEFAULT_PROVIDER = AIProvider.OPENAI;
|
|
41
|
-
const DEFAULT_TEMPERATURE = 1;
|
|
42
|
-
/**
|
|
43
|
-
* Get AI model configuration based on the selected provider and options
|
|
44
|
-
* This function handles the configuration for different AI providers
|
|
45
|
-
*
|
|
46
|
-
* @param options Configuration options including provider, API keys, models and temperature
|
|
47
|
-
* @returns Configured AI model ready to use with generateText
|
|
48
|
-
*/
|
|
49
|
-
const getAIConfig = async (res, options) => {
|
|
50
|
-
const { userOptions, defaultOptions, accessType = ["registered_user"] } = options;
|
|
51
|
-
const aiOptions = {
|
|
52
|
-
provider: DEFAULT_PROVIDER,
|
|
53
|
-
temperature: DEFAULT_TEMPERATURE,
|
|
54
|
-
...defaultOptions,
|
|
55
|
-
...userOptions
|
|
56
|
-
};
|
|
57
|
-
console.log({
|
|
58
|
-
aiOptions,
|
|
59
|
-
defaultOptions,
|
|
60
|
-
userOptions
|
|
61
|
-
});
|
|
62
|
-
const apiKey = getAPIKey(res, accessType, aiOptions);
|
|
63
|
-
if (!apiKey) throw new Error(`API key for ${aiOptions.provider} is missing`);
|
|
64
|
-
const selectedModel = getModel(aiOptions.provider, apiKey, aiOptions.model, defaultOptions?.model);
|
|
65
|
-
console.log({ selectedModel });
|
|
66
|
-
const protectedOptions = {
|
|
67
|
-
...aiOptions,
|
|
68
|
-
apiKey,
|
|
69
|
-
model: selectedModel
|
|
70
|
-
};
|
|
71
|
-
let languageModel;
|
|
72
|
-
switch (protectedOptions.provider) {
|
|
73
|
-
case AIProvider.OPENAI:
|
|
74
|
-
languageModel = createOpenAI({ apiKey })(selectedModel);
|
|
75
|
-
break;
|
|
76
|
-
case AIProvider.ANTHROPIC:
|
|
77
|
-
languageModel = createAnthropic({ apiKey })(selectedModel);
|
|
78
|
-
break;
|
|
79
|
-
case AIProvider.MISTRAL:
|
|
80
|
-
languageModel = createMistral({ apiKey })(selectedModel);
|
|
81
|
-
break;
|
|
82
|
-
case AIProvider.DEEPSEEK:
|
|
83
|
-
languageModel = createDeepSeek({ apiKey })(selectedModel);
|
|
84
|
-
break;
|
|
85
|
-
case AIProvider.GEMINI:
|
|
86
|
-
languageModel = createGoogleGenerativeAI({ apiKey })(selectedModel);
|
|
87
|
-
break;
|
|
88
|
-
default: throw new Error(`Provider ${protectedOptions.provider} not supported`);
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
model: languageModel,
|
|
92
|
-
temperature: protectedOptions.temperature
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
//#endregion
|
|
97
|
-
export { AIProvider, getAIConfig };
|
|
98
|
-
//# sourceMappingURL=aiSdk.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aiSdk.mjs","names":["DEFAULT_PROVIDER: AIProvider","DEFAULT_TEMPERATURE: number","languageModel: AIConfig['model']"],"sources":["../../../../src/utils/AI/aiSdk.ts"],"sourcesContent":["import { type anthropic, createAnthropic } from '@ai-sdk/anthropic';\nimport { createDeepSeek, type deepseek } from '@ai-sdk/deepseek';\nimport { createGoogleGenerativeAI, type google } from '@ai-sdk/google';\nimport { createMistral, type mistral } from '@ai-sdk/mistral';\nimport { createOpenAI, type openai } from '@ai-sdk/openai';\nimport type {\n AssistantModelMessage,\n generateText,\n SystemModelMessage,\n ToolModelMessage,\n UserModelMessage,\n} from 'ai';\nimport type { Response } from 'express';\n\ntype AnthropicModel = Parameters<typeof anthropic>[0];\ntype DeepSeekModel = Parameters<typeof deepseek>[0];\ntype MistralModel = Parameters<typeof mistral>[0];\ntype OpenAIModel = Parameters<typeof openai>[0];\ntype GoogleModel = Parameters<typeof google>[0];\n\nexport type Messages = (\n | SystemModelMessage\n | UserModelMessage\n | AssistantModelMessage\n | ToolModelMessage\n)[];\n\n/**\n * Supported AI models\n */\nexport type Model =\n | AnthropicModel\n | DeepSeekModel\n | MistralModel\n | OpenAIModel\n | GoogleModel\n | (string & {});\n\n/**\n * Supported AI SDK providers\n */\nexport enum AIProvider {\n OPENAI = 'openai',\n ANTHROPIC = 'anthropic',\n MISTRAL = 'mistral',\n DEEPSEEK = 'deepseek',\n GEMINI = 'gemini',\n}\n\n/**\n * Common options for all AI providers\n */\nexport type AIOptions = {\n provider?: AIProvider;\n model?: Model;\n temperature?: number;\n apiKey?: string;\n applicationContext?: string;\n};\n\n// Define the structure of messages used in chat completions\nexport type ChatCompletionRequestMessage = {\n role: 'system' | 'user' | 'assistant'; // The role of the message sender\n content: string; // The text content of the message\n timestamp?: Date; // The timestamp of the message\n};\n\ntype AccessType = 'apiKey' | 'registered_user' | 'premium_user' | 'public';\n\nconst getAPIKey = (\n res: Response,\n accessType: AccessType[],\n aiOptions?: AIOptions\n) => {\n const defaultApiKey = process.env.OPENAI_API_KEY;\n\n if (accessType.includes('public')) {\n return aiOptions?.apiKey ?? defaultApiKey;\n }\n\n if (accessType.includes('apiKey') && aiOptions?.apiKey) {\n return aiOptions?.apiKey;\n }\n\n if (accessType.includes('registered_user') && res.locals.user) {\n return aiOptions?.apiKey ?? defaultApiKey;\n }\n\n // TODO: Implement premium user access\n if (accessType.includes('premium_user') && res.locals.user) {\n return aiOptions?.apiKey ?? defaultApiKey;\n }\n\n return undefined;\n};\n\nconst getModel = (\n provider: AIProvider,\n userApiKey: string,\n userModel?: Model,\n defaultModel: Model = 'gpt-5-mini'\n): Model => {\n // If the user uses their own API key, allow custom model selection\n if (userApiKey) {\n if (provider && provider === AIProvider.OPENAI) {\n return userModel ?? defaultModel;\n }\n\n switch (provider) {\n case AIProvider.ANTHROPIC:\n return 'claude-sonnet-4-5-20250929';\n case AIProvider.MISTRAL:\n return 'mistral-large-latest';\n case AIProvider.DEEPSEEK:\n return 'deepseek-coder';\n case AIProvider.GEMINI:\n return 'gemini-2.5-flash';\n default:\n return defaultModel;\n }\n }\n\n // Guard: Prevent custom model usage without a user API key\n if (userModel || provider) {\n throw new Error(\n 'The user should use his own API key to use a custom model'\n );\n }\n\n return defaultModel;\n};\n\nexport type AIConfig = Omit<Parameters<typeof generateText>[0], 'prompt'>;\n\nconst DEFAULT_PROVIDER: AIProvider = AIProvider.OPENAI as AIProvider;\nconst DEFAULT_TEMPERATURE: number = 1; // ChatGPT 5 accept only temperature 1\n\nexport type AIConfigOptions = {\n userOptions?: AIOptions;\n defaultOptions?: AIOptions;\n accessType?: AccessType[];\n};\n\n/**\n * Get AI model configuration based on the selected provider and options\n * This function handles the configuration for different AI providers\n *\n * @param options Configuration options including provider, API keys, models and temperature\n * @returns Configured AI model ready to use with generateText\n */\nexport const getAIConfig = async (\n res: Response,\n options: AIConfigOptions\n): Promise<AIConfig> => {\n const {\n userOptions,\n defaultOptions,\n accessType = ['registered_user'],\n } = options;\n\n const aiOptions = {\n provider: DEFAULT_PROVIDER,\n temperature: DEFAULT_TEMPERATURE,\n ...defaultOptions,\n ...userOptions,\n } satisfies AIOptions;\n\n console.log({ aiOptions, defaultOptions, userOptions });\n\n const apiKey = getAPIKey(res, accessType, aiOptions);\n\n // Check if API key is provided\n if (!apiKey) {\n throw new Error(`API key for ${aiOptions.provider} is missing`);\n }\n\n const selectedModel = getModel(\n aiOptions.provider,\n apiKey,\n aiOptions.model,\n defaultOptions?.model\n );\n\n console.log({ selectedModel });\n\n const protectedOptions = {\n ...aiOptions,\n apiKey,\n model: selectedModel,\n } satisfies AIOptions;\n\n let languageModel: AIConfig['model'];\n\n switch (protectedOptions.provider) {\n case AIProvider.OPENAI: {\n languageModel = createOpenAI({\n apiKey,\n })(selectedModel);\n break;\n }\n\n case AIProvider.ANTHROPIC: {\n languageModel = createAnthropic({\n apiKey,\n })(selectedModel);\n break;\n }\n\n case AIProvider.MISTRAL: {\n languageModel = createMistral({\n apiKey,\n })(selectedModel);\n break;\n }\n\n case AIProvider.DEEPSEEK: {\n languageModel = createDeepSeek({\n apiKey,\n })(selectedModel);\n break;\n }\n\n case AIProvider.GEMINI: {\n languageModel = createGoogleGenerativeAI({\n apiKey,\n })(selectedModel);\n break;\n }\n\n default: {\n throw new Error(`Provider ${protectedOptions.provider} not supported`);\n }\n }\n\n return {\n model: languageModel,\n temperature: protectedOptions.temperature,\n };\n};\n"],"mappings":";;;;;;;;;;AAyCA,IAAY,oDAAL;AACL;AACA;AACA;AACA;AACA;;;AAuBF,MAAM,aACJ,KACA,YACA,cACG;CACH,MAAM,gBAAgB,QAAQ,IAAI;AAElC,KAAI,WAAW,SAAS,SAAS,CAC/B,QAAO,WAAW,UAAU;AAG9B,KAAI,WAAW,SAAS,SAAS,IAAI,WAAW,OAC9C,QAAO,WAAW;AAGpB,KAAI,WAAW,SAAS,kBAAkB,IAAI,IAAI,OAAO,KACvD,QAAO,WAAW,UAAU;AAI9B,KAAI,WAAW,SAAS,eAAe,IAAI,IAAI,OAAO,KACpD,QAAO,WAAW,UAAU;;AAMhC,MAAM,YACJ,UACA,YACA,WACA,eAAsB,iBACZ;AAEV,KAAI,YAAY;AACd,MAAI,YAAY,aAAa,WAAW,OACtC,QAAO,aAAa;AAGtB,UAAQ,UAAR;GACE,KAAK,WAAW,UACd,QAAO;GACT,KAAK,WAAW,QACd,QAAO;GACT,KAAK,WAAW,SACd,QAAO;GACT,KAAK,WAAW,OACd,QAAO;GACT,QACE,QAAO;;;AAKb,KAAI,aAAa,SACf,OAAM,IAAI,MACR,4DACD;AAGH,QAAO;;AAKT,MAAMA,mBAA+B,WAAW;AAChD,MAAMC,sBAA8B;;;;;;;;AAepC,MAAa,cAAc,OACzB,KACA,YACsB;CACtB,MAAM,EACJ,aACA,gBACA,aAAa,CAAC,kBAAkB,KAC9B;CAEJ,MAAM,YAAY;EAChB,UAAU;EACV,aAAa;EACb,GAAG;EACH,GAAG;EACJ;AAED,SAAQ,IAAI;EAAE;EAAW;EAAgB;EAAa,CAAC;CAEvD,MAAM,SAAS,UAAU,KAAK,YAAY,UAAU;AAGpD,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,eAAe,UAAU,SAAS,aAAa;CAGjE,MAAM,gBAAgB,SACpB,UAAU,UACV,QACA,UAAU,OACV,gBAAgB,MACjB;AAED,SAAQ,IAAI,EAAE,eAAe,CAAC;CAE9B,MAAM,mBAAmB;EACvB,GAAG;EACH;EACA,OAAO;EACR;CAED,IAAIC;AAEJ,SAAQ,iBAAiB,UAAzB;EACE,KAAK,WAAW;AACd,mBAAgB,aAAa,EAC3B,QACD,CAAC,CAAC,cAAc;AACjB;EAGF,KAAK,WAAW;AACd,mBAAgB,gBAAgB,EAC9B,QACD,CAAC,CAAC,cAAc;AACjB;EAGF,KAAK,WAAW;AACd,mBAAgB,cAAc,EAC5B,QACD,CAAC,CAAC,cAAc;AACjB;EAGF,KAAK,WAAW;AACd,mBAAgB,eAAe,EAC7B,QACD,CAAC,CAAC,cAAc;AACjB;EAGF,KAAK,WAAW;AACd,mBAAgB,yBAAyB,EACvC,QACD,CAAC,CAAC,cAAc;AACjB;EAGF,QACE,OAAM,IAAI,MAAM,YAAY,iBAAiB,SAAS,gBAAgB;;AAI1E,QAAO;EACL,OAAO;EACP,aAAa,iBAAiB;EAC/B"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { Response } from "express";
|
|
2
|
-
import { anthropic } from "@ai-sdk/anthropic";
|
|
3
|
-
import { deepseek } from "@ai-sdk/deepseek";
|
|
4
|
-
import { google } from "@ai-sdk/google";
|
|
5
|
-
import { mistral } from "@ai-sdk/mistral";
|
|
6
|
-
import { openai } from "@ai-sdk/openai";
|
|
7
|
-
import { AssistantModelMessage, SystemModelMessage, ToolModelMessage, UserModelMessage, generateText } from "ai";
|
|
8
|
-
|
|
9
|
-
//#region src/utils/AI/aiSdk.d.ts
|
|
10
|
-
type AnthropicModel = Parameters<typeof anthropic>[0];
|
|
11
|
-
type DeepSeekModel = Parameters<typeof deepseek>[0];
|
|
12
|
-
type MistralModel = Parameters<typeof mistral>[0];
|
|
13
|
-
type OpenAIModel = Parameters<typeof openai>[0];
|
|
14
|
-
type GoogleModel = Parameters<typeof google>[0];
|
|
15
|
-
type Messages = (SystemModelMessage | UserModelMessage | AssistantModelMessage | ToolModelMessage)[];
|
|
16
|
-
/**
|
|
17
|
-
* Supported AI models
|
|
18
|
-
*/
|
|
19
|
-
type Model = AnthropicModel | DeepSeekModel | MistralModel | OpenAIModel | GoogleModel | (string & {});
|
|
20
|
-
/**
|
|
21
|
-
* Supported AI SDK providers
|
|
22
|
-
*/
|
|
23
|
-
declare enum AIProvider {
|
|
24
|
-
OPENAI = "openai",
|
|
25
|
-
ANTHROPIC = "anthropic",
|
|
26
|
-
MISTRAL = "mistral",
|
|
27
|
-
DEEPSEEK = "deepseek",
|
|
28
|
-
GEMINI = "gemini",
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Common options for all AI providers
|
|
32
|
-
*/
|
|
33
|
-
type AIOptions = {
|
|
34
|
-
provider?: AIProvider;
|
|
35
|
-
model?: Model;
|
|
36
|
-
temperature?: number;
|
|
37
|
-
apiKey?: string;
|
|
38
|
-
applicationContext?: string;
|
|
39
|
-
};
|
|
40
|
-
type ChatCompletionRequestMessage = {
|
|
41
|
-
role: 'system' | 'user' | 'assistant';
|
|
42
|
-
content: string;
|
|
43
|
-
timestamp?: Date;
|
|
44
|
-
};
|
|
45
|
-
type AccessType = 'apiKey' | 'registered_user' | 'premium_user' | 'public';
|
|
46
|
-
type AIConfig = Omit<Parameters<typeof generateText>[0], 'prompt'>;
|
|
47
|
-
type AIConfigOptions = {
|
|
48
|
-
userOptions?: AIOptions;
|
|
49
|
-
defaultOptions?: AIOptions;
|
|
50
|
-
accessType?: AccessType[];
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Get AI model configuration based on the selected provider and options
|
|
54
|
-
* This function handles the configuration for different AI providers
|
|
55
|
-
*
|
|
56
|
-
* @param options Configuration options including provider, API keys, models and temperature
|
|
57
|
-
* @returns Configured AI model ready to use with generateText
|
|
58
|
-
*/
|
|
59
|
-
declare const getAIConfig: (res: Response, options: AIConfigOptions) => Promise<AIConfig>;
|
|
60
|
-
//#endregion
|
|
61
|
-
export { AIConfig, AIConfigOptions, AIOptions, AIProvider, ChatCompletionRequestMessage, Messages, Model, getAIConfig };
|
|
62
|
-
//# sourceMappingURL=aiSdk.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aiSdk.d.ts","names":[],"sources":["../../../../src/utils/AI/aiSdk.ts"],"sourcesContent":[],"mappings":";;;;;;;;;KAcK,cAAA,GAAiB,kBAAkB;KACnC,aAAA,GAAgB,kBAAkB;AAHC,KAInC,YAAA,GAAe,UAFD,CAAA,OAEmB,OAFhB,CAAA,CAAA,CAAA,CAAA;AAAU,KAG3B,WAAA,GAAc,UAFD,CAAA,OAEmB,MAFhB,CAAA,CAAA,CAAA,CAAA;AAAU,KAG1B,WAAA,GAAc,UAFF,CAAA,OAEoB,MAFjB,CAAA,CAAA,CAAA,CAAA;AACf,KAGO,QAAA,GAHI,CAIZ,kBAJe,GAKf,gBALyB,GAMzB,qBANyB,GAOzB,gBAPyB,CAAA,EAAA;AAAA;AAG7B;;AAEI,KAQQ,KAAA,GACR,cATA,GAUA,aAVA,GAWA,YAXA,GAYA,WAZA,GAaA,WAbA,GAAA,CAAA,MAAA,GAAA,CAAA,CAAA,CAAA;;;;AAQQ,aAWA,UAAA;EAVR,MAAA,GAAA,QAAA;EACA,SAAA,GAAA,WAAA;EACA,OAAA,GAAA,SAAA;EACA,QAAA,GAAA,UAAA;EACA,MAAA,GAAA,QAAA;;AAMJ;AAWA;AASA;AAMK,KAfO,SAAA,GAeG;EAiEH,QAAA,CAAA,EA/EC,UA+EO;EAA0B,KAAA,CAAA,EA9EpC,KA8EoC;EAAlB,WAAA,CAAA,EAAA,MAAA;EAAL,MAAA,CAAA,EAAA,MAAA;EAAI,kBAAA,CAAA,EAAA,MAAA;AAK3B,CAAA;AACgB,KA7EJ,4BAAA,GA6EI;EACG,IAAA,EAAA,QAAA,GAAA,MAAA,GAAA,WAAA;EACJ,OAAA,EAAA,MAAA;EAAU,SAAA,CAAA,EA5EX,IA4EW;AAUzB,CAAA;KAnFK,UAAA,GAoFE,QAAA,GAAA,iBAAA,GAAA,cAAA,GAAA,QAAA;AACI,KApBC,QAAA,GAAW,IAoBZ,CApBiB,UAoBjB,CAAA,OApBmC,YAoBnC,CAAA,CAAA,CAAA,CAAA,EAAA,QAAA,CAAA;AACA,KAhBC,eAAA,GAgBD;EAAR,WAAA,CAAA,EAfa,SAeb;EAAO,cAAA,CAAA,EAdS,SAcT;eAbK;;;;;;;;;cAUF,mBACN,mBACI,oBACR,QAAQ"}
|