@mate-academy/llm-gateway 0.0.1-canary.1

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 (109) hide show
  1. package/.lintstagedrc +5 -0
  2. package/.nvmrc +1 -0
  3. package/dist/LLMService.constants.d.ts +8 -0
  4. package/dist/LLMService.constants.js +16 -0
  5. package/dist/LLMService.constants.js.map +1 -0
  6. package/dist/LLMService.entity.d.ts +13 -0
  7. package/dist/LLMService.entity.js +38 -0
  8. package/dist/LLMService.entity.js.map +1 -0
  9. package/dist/LLMService.factory.d.ts +8 -0
  10. package/dist/LLMService.factory.js +28 -0
  11. package/dist/LLMService.factory.js.map +1 -0
  12. package/dist/LLMService.typedefs.d.ts +126 -0
  13. package/dist/LLMService.typedefs.js +24 -0
  14. package/dist/LLMService.typedefs.js.map +1 -0
  15. package/dist/functional.utils.d.ts +1 -0
  16. package/dist/functional.utils.js +9 -0
  17. package/dist/functional.utils.js.map +1 -0
  18. package/dist/index.d.ts +6 -0
  19. package/dist/index.js +23 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.constants.d.ts +6 -0
  22. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.constants.js +98 -0
  23. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.constants.js.map +1 -0
  24. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.d.ts +8 -0
  25. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.js +42 -0
  26. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.js.map +1 -0
  27. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.typedefs.d.ts +13 -0
  28. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.typedefs.js +19 -0
  29. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.typedefs.js.map +1 -0
  30. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.d.ts +6 -0
  31. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.js +17 -0
  32. package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.js.map +1 -0
  33. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.d.ts +21 -0
  34. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.js +209 -0
  35. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.js.map +1 -0
  36. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.d.ts +10 -0
  37. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.js +50 -0
  38. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.js.map +1 -0
  39. package/dist/providers/GoogleGenerativeAI/services/index.d.ts +2 -0
  40. package/dist/providers/GoogleGenerativeAI/services/index.js +19 -0
  41. package/dist/providers/GoogleGenerativeAI/services/index.js.map +1 -0
  42. package/dist/providers/OpenAI/OpenAI.constants.d.ts +5 -0
  43. package/dist/providers/OpenAI/OpenAI.constants.js +44 -0
  44. package/dist/providers/OpenAI/OpenAI.constants.js.map +1 -0
  45. package/dist/providers/OpenAI/OpenAI.entity.d.ts +3 -0
  46. package/dist/providers/OpenAI/OpenAI.entity.js +15 -0
  47. package/dist/providers/OpenAI/OpenAI.entity.js.map +1 -0
  48. package/dist/providers/OpenAI/OpenAI.typedefs.d.ts +8 -0
  49. package/dist/providers/OpenAI/OpenAI.typedefs.js +14 -0
  50. package/dist/providers/OpenAI/OpenAI.typedefs.js.map +1 -0
  51. package/dist/providers/OpenAI/OpenAIService.factory.d.ts +6 -0
  52. package/dist/providers/OpenAI/OpenAIService.factory.js +17 -0
  53. package/dist/providers/OpenAI/OpenAIService.factory.js.map +1 -0
  54. package/dist/providers/OpenAI/services/OpenAIAssistance.service.d.ts +19 -0
  55. package/dist/providers/OpenAI/services/OpenAIAssistance.service.js +200 -0
  56. package/dist/providers/OpenAI/services/OpenAIAssistance.service.js.map +1 -0
  57. package/dist/providers/OpenAI/services/OpenAICompletion.service.d.ts +10 -0
  58. package/dist/providers/OpenAI/services/OpenAICompletion.service.js +52 -0
  59. package/dist/providers/OpenAI/services/OpenAICompletion.service.js.map +1 -0
  60. package/dist/providers/OpenAI/services/index.d.ts +2 -0
  61. package/dist/providers/OpenAI/services/index.js +19 -0
  62. package/dist/providers/OpenAI/services/index.js.map +1 -0
  63. package/dist/providers/index.d.ts +2 -0
  64. package/dist/providers/index.js +19 -0
  65. package/dist/providers/index.js.map +1 -0
  66. package/dist/services/LLMAssistanceService.abstract.d.ts +15 -0
  67. package/dist/services/LLMAssistanceService.abstract.js +12 -0
  68. package/dist/services/LLMAssistanceService.abstract.js.map +1 -0
  69. package/dist/services/LLMBaseService.abstract.d.ts +13 -0
  70. package/dist/services/LLMBaseService.abstract.js +27 -0
  71. package/dist/services/LLMBaseService.abstract.js.map +1 -0
  72. package/dist/services/LLMCompletionService.abstract.d.ts +7 -0
  73. package/dist/services/LLMCompletionService.abstract.js +12 -0
  74. package/dist/services/LLMCompletionService.abstract.js.map +1 -0
  75. package/dist/services/LLMServicePurposeFactory.abstract.d.ts +5 -0
  76. package/dist/services/LLMServicePurposeFactory.abstract.js +7 -0
  77. package/dist/services/LLMServicePurposeFactory.abstract.js.map +1 -0
  78. package/dist/services/index.d.ts +4 -0
  79. package/dist/services/index.js +21 -0
  80. package/dist/services/index.js.map +1 -0
  81. package/eslint.config.mjs +39 -0
  82. package/package.json +35 -0
  83. package/src/LLMService.constants.ts +19 -0
  84. package/src/LLMService.entity.ts +71 -0
  85. package/src/LLMService.factory.ts +57 -0
  86. package/src/LLMService.typedefs.ts +174 -0
  87. package/src/functional.utils.ts +7 -0
  88. package/src/index.ts +6 -0
  89. package/src/providers/GoogleGenerativeAI/GoogleGenerativeAI.constants.ts +127 -0
  90. package/src/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.ts +67 -0
  91. package/src/providers/GoogleGenerativeAI/GoogleGenerativeAI.typedefs.ts +14 -0
  92. package/src/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.ts +29 -0
  93. package/src/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.ts +307 -0
  94. package/src/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.ts +79 -0
  95. package/src/providers/GoogleGenerativeAI/services/index.ts +2 -0
  96. package/src/providers/OpenAI/OpenAI.constants.ts +71 -0
  97. package/src/providers/OpenAI/OpenAI.entity.ts +17 -0
  98. package/src/providers/OpenAI/OpenAI.typedefs.ts +9 -0
  99. package/src/providers/OpenAI/OpenAIService.factory.ts +29 -0
  100. package/src/providers/OpenAI/services/OpenAIAssistance.service.ts +304 -0
  101. package/src/providers/OpenAI/services/OpenAICompletion.service.ts +74 -0
  102. package/src/providers/OpenAI/services/index.ts +2 -0
  103. package/src/providers/index.ts +2 -0
  104. package/src/services/LLMAssistanceService.abstract.ts +73 -0
  105. package/src/services/LLMBaseService.abstract.ts +34 -0
  106. package/src/services/LLMCompletionService.abstract.ts +32 -0
  107. package/src/services/LLMServicePurposeFactory.abstract.ts +15 -0
  108. package/src/services/index.ts +4 -0
  109. package/tsconfig.json +23 -0
@@ -0,0 +1,71 @@
1
+ import {
2
+ LLMCountTokensFunction,
3
+ LLMMessage,
4
+ LLMModel,
5
+ LLMProviders,
6
+ LLMRoles,
7
+ } from './LLMService.typedefs';
8
+
9
+ interface CombineMessagesOptions<Provider extends LLMProviders> {
10
+ modelContext?: LLMMessage[];
11
+ history?: LLMMessage[];
12
+ message: string;
13
+ model: LLMModel<Provider>;
14
+ countTokensFn?: LLMCountTokensFunction<Provider>;
15
+ }
16
+
17
+ export class LLMServiceEntity {
18
+ private static countTokensFallback(messages: string[]): Promise<number> {
19
+ const message = messages.join('');
20
+ const basicTokens = message.split(/[\s,.;!?(){}[\]<>%&]+/).filter(Boolean);
21
+ const subwordTokens = basicTokens.flatMap((token) => (
22
+ token.split(
23
+ /(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-zA-Z])(?=\d)|(?<=[\d])(?=[a-zA-Z])/,
24
+ )
25
+ ));
26
+
27
+ return Promise.resolve(subwordTokens.length);
28
+ }
29
+
30
+ static async combineMessagesWithLimit<Provider extends LLMProviders>({
31
+ modelContext = [],
32
+ history = [],
33
+ message,
34
+ model,
35
+ countTokensFn = this.countTokensFallback,
36
+ }: CombineMessagesOptions<Provider>): Promise<LLMMessage[]> {
37
+ const combinedMessages: LLMMessage[] = [...modelContext];
38
+
39
+ if (history[0]) {
40
+ const firstHistoryMessage = history[0];
41
+
42
+ combinedMessages.push(firstHistoryMessage);
43
+ }
44
+
45
+ const messagesToConsider = [
46
+ { role: LLMRoles.User, content: message },
47
+ ...history.slice(1).reverse(),
48
+ ];
49
+
50
+ const messages = combinedMessages.map(
51
+ (combinedMessage) => combinedMessage.content,
52
+ );
53
+
54
+ let tokenCount = await countTokensFn(messages, model);
55
+
56
+ for (const msg of messagesToConsider) {
57
+ const tempTokenCount = tokenCount + (
58
+ await countTokensFn([msg.content], model)
59
+ );
60
+
61
+ if (tempTokenCount <= model.limits.maxInputTokens) {
62
+ combinedMessages.push(msg);
63
+ tokenCount = tempTokenCount;
64
+ } else {
65
+ break;
66
+ }
67
+ }
68
+
69
+ return combinedMessages;
70
+ }
71
+ }
@@ -0,0 +1,57 @@
1
+ import { Logger } from '@mate-academy/core';
2
+ import {
3
+ LLMInstanceOptions,
4
+ LLMProviders,
5
+ LLMPurposes,
6
+ LLMServiceByPurpose,
7
+ } from './LLMService.typedefs';
8
+ import { LLM_SERVICE_FACTORIES } from './LLMService.constants';
9
+
10
+ export class LLMServiceFactory {
11
+ private static getService<
12
+ Purpose extends LLMPurposes,
13
+ Provider extends LLMProviders,
14
+ >(
15
+ purpose: Purpose,
16
+ provider: Provider,
17
+ logger: Logger,
18
+ options: LLMInstanceOptions[Provider ],
19
+ ): LLMServiceByPurpose<Provider>[Purpose] {
20
+ switch (provider) {
21
+ case LLMProviders.OpenAI:
22
+ case LLMProviders.GoogleGenerativeAI:
23
+ return LLM_SERVICE_FACTORIES[provider]
24
+ .createService(
25
+ purpose,
26
+ logger,
27
+ options,
28
+ );
29
+
30
+ default:
31
+ throw new Error(`Provider [${provider}] is not supported`);
32
+ }
33
+ }
34
+
35
+ static getCompletionService<Provider extends LLMProviders>(
36
+ provider: Provider,
37
+ logger: Logger,
38
+ options: LLMInstanceOptions[Provider],
39
+ ): LLMServiceByPurpose<Provider>[LLMPurposes.Completion] {
40
+ return this.getService(LLMPurposes.Completion, provider, logger, options);
41
+ }
42
+
43
+ static getAssistanceService<Provider extends LLMProviders>(
44
+ provider: Provider,
45
+ logger: Logger,
46
+ options: LLMInstanceOptions[Provider],
47
+ ): LLMServiceByPurpose<Provider>[LLMPurposes.Assistance] {
48
+ return this.getService(LLMPurposes.Assistance, provider, logger, options);
49
+ }
50
+
51
+ static resolveProviderOptions<Provider extends LLMProviders>(
52
+ provider: Provider,
53
+ options: Record<Provider, LLMInstanceOptions[Provider]>,
54
+ ): LLMInstanceOptions[Provider] {
55
+ return options[provider];
56
+ }
57
+ }
@@ -0,0 +1,174 @@
1
+ import { Logger } from '@mate-academy/core';
2
+ import { ClientOptions, OpenAI } from 'openai';
3
+ import { GoogleGenAI } from '@google/genai';
4
+ import { OpenAIModelNames } from './providers/OpenAI/OpenAI.typedefs';
5
+ import { GoogleGenerativeAIModelNames } from './providers/GoogleGenerativeAI/GoogleGenerativeAI.typedefs';
6
+ import { LLMCompletionService } from './services/LLMCompletionService.abstract';
7
+ import { LLMAssistanceService } from './services/LLMAssistanceService.abstract';
8
+
9
+ export enum LLMProviders {
10
+ OpenAI = 'OpenAI',
11
+ GoogleGenerativeAI = 'GoogleGenerativeAI',
12
+ }
13
+
14
+ export type LLMInstances = {
15
+ [LLMProviders.OpenAI]: OpenAI;
16
+ [LLMProviders.GoogleGenerativeAI]: GoogleGenAI;
17
+ };
18
+
19
+ export type LLMInstanceOptions = {
20
+ [LLMProviders.OpenAI]: ClientOptions;
21
+ [LLMProviders.GoogleGenerativeAI]: { apiKey: string };
22
+ };
23
+
24
+ export enum LLMPurposes {
25
+ Completion = 'completion',
26
+ Assistance = 'assistance',
27
+ }
28
+
29
+ export type LLMServiceByPurpose<Provider extends LLMProviders> = {
30
+ [LLMPurposes.Completion]: LLMCompletionService<Provider>;
31
+ [LLMPurposes.Assistance]: LLMAssistanceService<Provider>;
32
+ };
33
+
34
+ export type LLMServiceBuilder<
35
+ Provider extends LLMProviders,
36
+ Purpose extends LLMPurposes,
37
+ > = (
38
+ logger: Logger,
39
+ options: LLMInstanceOptions[Provider],
40
+ ) => LLMServiceByPurpose<Provider>[Purpose];
41
+
42
+ export interface LLMLimits {
43
+ maxInputTokens: number;
44
+ maxOutputTokens: number;
45
+ }
46
+
47
+ export interface LLMConfig {
48
+ temperature?: number;
49
+ top_p?: number | null;
50
+ }
51
+
52
+ export type LLMProviderAvailableModels<
53
+ Provider extends LLMProviders
54
+ > = Record<
55
+ LLMModelName[Provider],
56
+ LLMModel<Provider>
57
+ >;
58
+
59
+ export type LLMProviderModelsByPurpose<
60
+ Purpose extends LLMPurposes,
61
+ Provider extends LLMProviders
62
+ > = Record<
63
+ Purpose,
64
+ Partial<LLMProviderAvailableModels<Provider>>
65
+ >;
66
+
67
+ export type LLMModelName = {
68
+ [LLMProviders.OpenAI]: OpenAIModelNames;
69
+ [LLMProviders.GoogleGenerativeAI]: GoogleGenerativeAIModelNames;
70
+ };
71
+
72
+ export interface LLMModel<Provider extends LLMProviders> {
73
+ name: LLMModelName[Provider];
74
+ limits: LLMLimits;
75
+ config: LLMConfig;
76
+ }
77
+
78
+ export enum LLMRoles {
79
+ User = 'user',
80
+ Assistant = 'assistant',
81
+ }
82
+
83
+ export interface LLMMessage {
84
+ role: LLMRoles;
85
+ content: string;
86
+ }
87
+
88
+ export type LLMRequestError = Error;
89
+
90
+ export type LLMRequestResult<Result> = Result | { error: LLMRequestError };
91
+
92
+ export type LLMCompletionResult = LLMRequestResult<{ text: string }>;
93
+ export interface LLMSendMessageOptions<Provider extends LLMProviders> {
94
+ message: LLMMessage;
95
+ model: LLMModel<Provider>;
96
+ history?: LLMMessage[];
97
+ instructions?: string;
98
+ }
99
+
100
+ export enum LLMUploadFileMimeTypes {
101
+ PNG = 'image/png',
102
+ PLAIN_TEXT = 'text/plain',
103
+ }
104
+
105
+ export interface LLMUploadFile {
106
+ mimeType: LLMUploadFileMimeTypes;
107
+ name: string;
108
+ path: string;
109
+ }
110
+
111
+ export interface LLMUploadedFile extends LLMUploadFile {
112
+ fileId: string;
113
+ }
114
+
115
+ export type LLMUploadFileResult = LLMRequestResult<LLMUploadedFile>;
116
+
117
+ export interface LLMCreateFileStorageOptions<Provider extends LLMProviders> {
118
+ uploadedFiles: LLMUploadedFile[];
119
+ model: LLMModel<Provider>;
120
+ instructions?: string;
121
+ }
122
+
123
+ export interface LLMCreatedFileStorage {
124
+ storageId: string;
125
+ }
126
+
127
+ export type LLMCreateFileStorageResult = LLMRequestResult<
128
+ LLMCreatedFileStorage
129
+ >;
130
+
131
+ export interface LLMCreateAssistantOptions<Provider extends LLMProviders> {
132
+ model: LLMModel<Provider>;
133
+ instructions?: string;
134
+ storageIds?: string[];
135
+ }
136
+
137
+ export interface LLMCreatedAssistant {
138
+ assistantId: string;
139
+ }
140
+
141
+ export type LLMCreateAssistantResult = LLMRequestResult<LLMCreatedAssistant>;
142
+
143
+ export interface LLMCreateChatOptions<Provider extends LLMProviders> {
144
+ model: LLMModel<Provider>;
145
+ instructions?: string;
146
+ history?: string[];
147
+ files?: LLMUploadedFile[];
148
+ storageId?: string;
149
+ }
150
+
151
+ export interface LLMCreatedChat {
152
+ chatId: string;
153
+ }
154
+
155
+ export type LLMCreateChatResult = LLMRequestResult<LLMCreatedChat>;
156
+
157
+ export interface LLMAssistanceMessage extends LLMMessage {
158
+ attachment?: LLMUploadFileResult;
159
+ instructions?: string;
160
+ }
161
+
162
+ export interface LLMAssistanceOptions<Provider extends LLMProviders> {
163
+ model: LLMModel<Provider>;
164
+ message: LLMAssistanceMessage;
165
+ chatId: string;
166
+ assistantId: string;
167
+ }
168
+
169
+ export type LLMAssistanceResult = LLMRequestResult<{ text: string }>;
170
+
171
+ export type LLMCountTokensFunction<Provider extends LLMProviders> = (
172
+ messages: string[],
173
+ model: LLMModel<Provider>,
174
+ ) => Promise<number>;
@@ -0,0 +1,7 @@
1
+ export const pick = <T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> => (
2
+ keys.reduce((acc, key) => {
3
+ Object.assign(acc, { [key]: obj[key] });
4
+
5
+ return acc;
6
+ }, {} as Pick<T, K>)
7
+ );
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './LLMService.constants';
2
+ export * from './LLMService.entity';
3
+ export * from './LLMService.factory';
4
+ export * from './LLMService.typedefs';
5
+ export * from './providers';
6
+ export * from './services';
@@ -0,0 +1,127 @@
1
+ import {
2
+ LLMProviderAvailableModels,
3
+ LLMProviderModelsByPurpose,
4
+ LLMProviders,
5
+ LLMPurposes,
6
+ LLMServiceBuilder,
7
+ } from '../../LLMService.typedefs';
8
+ import { GoogleGenerativeAIModelNames } from './GoogleGenerativeAI.typedefs';
9
+ import {
10
+ GoogleGenerativeAIAssistanceService,
11
+ GoogleGenerativeAICompletionService,
12
+ } from '../../providers/GoogleGenerativeAI/services';
13
+ import { pick } from '../../functional.utils';
14
+
15
+ export const MIN_CACHE_CONTENT_LENGTH = 32_768;
16
+
17
+ const GOOGLE_AI_AVAILABLE_MODELS: LLMProviderAvailableModels<
18
+ LLMProviders.GoogleGenerativeAI
19
+ > = {
20
+ [GoogleGenerativeAIModelNames.GEMINI_1_5_FLASH]: {
21
+ name: GoogleGenerativeAIModelNames.GEMINI_1_5_FLASH,
22
+ limits: {
23
+ maxInputTokens: 1_048_576,
24
+ maxOutputTokens: 8_192,
25
+ },
26
+ config: {
27
+ temperature: 0.2,
28
+ },
29
+ },
30
+ [GoogleGenerativeAIModelNames.GEMINI_1_5_FLASH_STABLE]: {
31
+ name: GoogleGenerativeAIModelNames.GEMINI_1_5_FLASH_STABLE,
32
+ limits: {
33
+ maxInputTokens: 1_048_576,
34
+ maxOutputTokens: 8_192,
35
+ },
36
+ config: {
37
+ temperature: 0.2,
38
+ },
39
+ },
40
+ [GoogleGenerativeAIModelNames.GEMINI_1_5_PRO]: {
41
+ name: GoogleGenerativeAIModelNames.GEMINI_1_5_PRO,
42
+ limits: {
43
+ maxInputTokens: 2_097_152,
44
+ maxOutputTokens: 8_192,
45
+ },
46
+ config: {
47
+ temperature: 0.2,
48
+ },
49
+ },
50
+ [GoogleGenerativeAIModelNames.GEMINI_1_5_PRO_STABLE]: {
51
+ name: GoogleGenerativeAIModelNames.GEMINI_1_5_PRO_STABLE,
52
+ limits: {
53
+ maxInputTokens: 2_097_152,
54
+ maxOutputTokens: 8_192,
55
+ },
56
+ config: {
57
+ temperature: 0.2,
58
+ },
59
+ },
60
+ [GoogleGenerativeAIModelNames.GEMINI_2_0_FLASH]: {
61
+ name: GoogleGenerativeAIModelNames.GEMINI_2_0_FLASH,
62
+ limits: {
63
+ maxInputTokens: 1_048_576,
64
+ maxOutputTokens: 8_192,
65
+ },
66
+ config: {
67
+ temperature: 0.2,
68
+ },
69
+ },
70
+ [GoogleGenerativeAIModelNames.GEMINI_2_0_FLASH_STABLE]: {
71
+ name: GoogleGenerativeAIModelNames.GEMINI_2_0_FLASH_STABLE,
72
+ limits: {
73
+ maxInputTokens: 1_048_576,
74
+ maxOutputTokens: 8_192,
75
+ },
76
+ config: {
77
+ temperature: 0.2,
78
+ },
79
+ },
80
+ [GoogleGenerativeAIModelNames.GEMINI_2_5_PRO_PREVIEW]: {
81
+ name: GoogleGenerativeAIModelNames.GEMINI_2_5_PRO_PREVIEW,
82
+ limits: {
83
+ maxInputTokens: 1_048_576,
84
+ maxOutputTokens: 65_536,
85
+ },
86
+ config: {
87
+ temperature: 0.2,
88
+ },
89
+ },
90
+ };
91
+
92
+ export const GOOGLE_AI_MODELS: LLMProviderModelsByPurpose<
93
+ LLMPurposes,
94
+ LLMProviders.GoogleGenerativeAI
95
+ > = {
96
+ [LLMPurposes.Completion]: pick(
97
+ GOOGLE_AI_AVAILABLE_MODELS,
98
+ [
99
+ GoogleGenerativeAIModelNames.GEMINI_1_5_FLASH,
100
+ GoogleGenerativeAIModelNames.GEMINI_1_5_PRO,
101
+ GoogleGenerativeAIModelNames.GEMINI_2_0_FLASH,
102
+ GoogleGenerativeAIModelNames.GEMINI_2_5_PRO_PREVIEW,
103
+ ],
104
+ ),
105
+ // Stable models are used for assistance as they support additional methods
106
+ [LLMPurposes.Assistance]: pick(
107
+ GOOGLE_AI_AVAILABLE_MODELS,
108
+ [
109
+ GoogleGenerativeAIModelNames.GEMINI_1_5_FLASH_STABLE,
110
+ GoogleGenerativeAIModelNames.GEMINI_1_5_PRO_STABLE,
111
+ GoogleGenerativeAIModelNames.GEMINI_2_0_FLASH_STABLE,
112
+ ],
113
+ ),
114
+ };
115
+
116
+ export const GOOGLE_AI_SERVICE_BUILDERS: {
117
+ [purpose in LLMPurposes]: (
118
+ LLMServiceBuilder<LLMProviders.GoogleGenerativeAI, purpose> | null
119
+ )
120
+ } = {
121
+ [LLMPurposes.Completion]: (logger, options) => (
122
+ new GoogleGenerativeAICompletionService(logger, options)
123
+ ),
124
+ [LLMPurposes.Assistance]: (logger, options) => (
125
+ new GoogleGenerativeAIAssistanceService(logger, options)
126
+ ),
127
+ };
@@ -0,0 +1,67 @@
1
+ import {
2
+ Part,
3
+ GoogleGenAI,
4
+ ContentListUnion,
5
+ GenerateContentParameters,
6
+ } from '@google/genai';
7
+ import {
8
+ LLMMessage,
9
+ LLMModel,
10
+ LLMProviders,
11
+ LLMUploadedFile,
12
+ } from '../../LLMService.typedefs';
13
+
14
+ export class GoogleGenerativeAIEntity {
15
+ static getContentParameters(
16
+ model: LLMModel<LLMProviders.GoogleGenerativeAI>,
17
+ messages: LLMMessage[],
18
+ instructions?: string,
19
+ ): GenerateContentParameters {
20
+ return {
21
+ model: model.name,
22
+ contents: messages.map((message) => ({
23
+ parts: [{
24
+ text: message.content,
25
+ }],
26
+ role: message.role,
27
+ })),
28
+ config: {
29
+ systemInstruction: instructions,
30
+ temperature: model.config.temperature,
31
+ },
32
+ };
33
+ }
34
+
35
+ static getFileDataParts(
36
+ uploadedFiles: LLMUploadedFile[],
37
+ ): Pick<Part, 'fileData'>[] {
38
+ return uploadedFiles.map((file) => ({
39
+ fileData: {
40
+ fileUri: file.path,
41
+ mimeType: file.mimeType,
42
+ },
43
+ }));
44
+ }
45
+
46
+ static getTextParts(
47
+ messages: string[],
48
+ ): Pick<Part, 'text'>[] {
49
+ return messages.map((message) => ({ text: message }));
50
+ }
51
+
52
+ static getCountTokensFn(
53
+ instance: GoogleGenAI,
54
+ ) {
55
+ return async (
56
+ contents: ContentListUnion,
57
+ model: LLMModel<LLMProviders.GoogleGenerativeAI>,
58
+ ): Promise<number> => {
59
+ const tokenCount = await instance.models.countTokens({
60
+ model: model.name,
61
+ contents,
62
+ });
63
+
64
+ return tokenCount.totalTokens ?? 0;
65
+ };
66
+ }
67
+ }
@@ -0,0 +1,14 @@
1
+ export enum GoogleGenerativeAIModelNames {
2
+ GEMINI_1_5_FLASH = 'gemini-1.5-flash',
3
+ GEMINI_1_5_FLASH_STABLE = 'gemini-1.5-flash-001',
4
+ GEMINI_1_5_PRO = 'gemini-1.5-pro',
5
+ GEMINI_1_5_PRO_STABLE = 'gemini-1.5-pro-002',
6
+ GEMINI_2_0_FLASH = 'gemini-2.0-flash',
7
+ GEMINI_2_0_FLASH_STABLE = 'gemini-2.0-flash-001',
8
+ GEMINI_2_5_PRO_PREVIEW = 'gemini-2.5-pro-preview-03-25',
9
+ }
10
+
11
+ export enum GoogleGenerativeAIRoles {
12
+ User = 'user',
13
+ Model = 'model',
14
+ }
@@ -0,0 +1,29 @@
1
+ import { Logger } from '@mate-academy/core';
2
+ import {
3
+ LLMInstanceOptions,
4
+ LLMProviders,
5
+ LLMPurposes,
6
+ LLMServiceByPurpose,
7
+ } from '../../LLMService.typedefs';
8
+ import { LLMServicePurposeFactory } from '../../services';
9
+ import { GOOGLE_AI_SERVICE_BUILDERS } from './GoogleGenerativeAI.constants';
10
+
11
+ export class GoogleGenerativeAIServiceFactory extends LLMServicePurposeFactory<
12
+ LLMProviders.GoogleGenerativeAI
13
+ > {
14
+ createService<
15
+ Purpose extends LLMPurposes
16
+ >(
17
+ purpose: Purpose,
18
+ logger: Logger,
19
+ options: LLMInstanceOptions[LLMProviders.GoogleGenerativeAI],
20
+ ): LLMServiceByPurpose<LLMProviders.GoogleGenerativeAI>[Purpose] {
21
+ const serviceBuilder = GOOGLE_AI_SERVICE_BUILDERS[purpose];
22
+
23
+ if (!serviceBuilder) {
24
+ throw new Error(`Purpose [${purpose}] is not supported for [${LLMProviders.GoogleGenerativeAI}] service`);
25
+ }
26
+
27
+ return serviceBuilder(logger, options);
28
+ }
29
+ }