@yrpri/api 9.0.88 → 9.0.90

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.
@@ -0,0 +1,488 @@
1
+ import { sequelize as psSequelize } from "@policysynth/agents/dbModels/index.js";
2
+ import { PsAiModel } from "@policysynth/agents/dbModels/aiModel.js";
3
+ import { PsAgentClass } from "@policysynth/agents/dbModels/agentClass.js";
4
+ import { PsAgentClassCategories } from "@policysynth/agents/agentCategories.js";
5
+ import { PsExternalApiUsage } from "@policysynth/agents/dbModels/externalApiUsage.js";
6
+ import { PsExternalApi } from "@policysynth/agents/dbModels/externalApis.js";
7
+ import { PsModelUsage } from "@policysynth/agents/dbModels/modelUsage.js";
8
+ import { PsAgent } from "@policysynth/agents/dbModels/agent.js";
9
+ import { PsAgentAuditLog } from "@policysynth/agents/dbModels/agentAuditLog.js";
10
+ import { PsAgentConnector } from "@policysynth/agents/dbModels/agentConnector.js";
11
+ import { PsAgentConnectorClass } from "@policysynth/agents/dbModels/agentConnectorClass.js";
12
+ import { PsAgentRegistry } from "@policysynth/agents/dbModels/agentRegistry.js";
13
+ import { PsAiModelSize, PsAiModelType, } from "@policysynth/agents/aiModelTypes.js";
14
+ import models from "../../models/index.cjs";
15
+ const dbModels = models;
16
+ const Group = dbModels.Group; // for reference elsewhere if needed
17
+ // List of models that need to be initialized/associated
18
+ const psModels = {
19
+ PsAgentClass,
20
+ PsExternalApiUsage,
21
+ PsModelUsage,
22
+ PsAgentConnector,
23
+ PsAgent,
24
+ PsAgentAuditLog,
25
+ PsAgentConnectorClass,
26
+ PsAgentRegistry,
27
+ PsAiModel,
28
+ PsExternalApi,
29
+ };
30
+ export class NewAiModelSetup {
31
+ /**
32
+ * Initializes all models by calling their associate methods (if present).
33
+ */
34
+ static async initializeModels() {
35
+ try {
36
+ console.log("All Models Loaded Init");
37
+ for (const modelName of Object.keys(psModels)) {
38
+ if (typeof psModels[modelName].associate === "function") {
39
+ await psModels[modelName].associate(psSequelize.models);
40
+ }
41
+ }
42
+ console.log("All models initialized successfully.");
43
+ }
44
+ catch (error) {
45
+ console.error("Error initializing models:", error);
46
+ process.exit(1);
47
+ }
48
+ }
49
+ /**
50
+ * Seeds the test AI models (and a top-level agent class) if they do not exist.
51
+ * @param userId the user id to associate with the new models
52
+ */
53
+ static async seedAnthropicModels(userId) {
54
+ const anthropicSonnet = await PsAiModel.findOne({
55
+ where: { name: "Anthropic Sonnet 3.5" },
56
+ });
57
+ if (!anthropicSonnet) {
58
+ const anthropicSonnetConfig = {
59
+ type: PsAiModelType.Text,
60
+ modelSize: PsAiModelSize.Medium,
61
+ provider: "anthropic",
62
+ prices: {
63
+ costInTokensPerMillion: 3,
64
+ costOutTokensPerMillion: 15,
65
+ currency: "USD",
66
+ },
67
+ maxTokensOut: 8000,
68
+ defaultTemperature: 0.7,
69
+ model: "claude-3-5-sonnet-20240620",
70
+ active: true,
71
+ };
72
+ const createdModel = await PsAiModel.create({
73
+ name: "Anthropic Sonnet 3.5",
74
+ organization_id: 1,
75
+ user_id: userId,
76
+ configuration: anthropicSonnetConfig,
77
+ });
78
+ console.log("Created Anthropic model:", createdModel);
79
+ }
80
+ else {
81
+ console.log("Anthropic model already exists: Anthropic Sonnet 3.5");
82
+ }
83
+ }
84
+ /**
85
+ * Seeds OpenAI models.
86
+ * This currently creates several models including GPT-4o, GPT-4o Mini, o1 Mini,
87
+ * o1 Preview, o1 24, and o3 mini.
88
+ */
89
+ static async seedOpenAiModels(userId) {
90
+ // GPT-4o
91
+ const openAiGpt4 = await PsAiModel.findOne({
92
+ where: { name: "GPT-4o" },
93
+ });
94
+ const openAiGpt4oConfig = {
95
+ type: PsAiModelType.Text,
96
+ modelSize: PsAiModelSize.Medium,
97
+ provider: "openai",
98
+ prices: {
99
+ costInTokensPerMillion: 2.5,
100
+ costOutTokensPerMillion: 10,
101
+ currency: "USD",
102
+ },
103
+ maxTokensOut: 16384,
104
+ defaultTemperature: 0.7,
105
+ model: "gpt-4o",
106
+ active: true,
107
+ };
108
+ if (!openAiGpt4) {
109
+ await PsAiModel.create({
110
+ name: "GPT-4o",
111
+ organization_id: 1,
112
+ user_id: userId,
113
+ configuration: openAiGpt4oConfig,
114
+ });
115
+ console.log("Created OpenAI model: GPT-4o");
116
+ }
117
+ else {
118
+ console.log("OpenAI model already exists: GPT-4o updating");
119
+ openAiGpt4.set("configuration", openAiGpt4oConfig);
120
+ openAiGpt4.changed("configuration", true);
121
+ await openAiGpt4.save();
122
+ }
123
+ // GPT-4o Mini
124
+ const openAiGpt4Mini = await PsAiModel.findOne({
125
+ where: { name: "GPT-4o Mini" },
126
+ });
127
+ if (!openAiGpt4Mini) {
128
+ const openAiGpt4oMiniConfig = {
129
+ type: PsAiModelType.Text,
130
+ modelSize: PsAiModelSize.Small,
131
+ provider: "openai",
132
+ prices: {
133
+ costInTokensPerMillion: 0.15,
134
+ costOutTokensPerMillion: 0.6,
135
+ currency: "USD",
136
+ },
137
+ maxTokensOut: 16384,
138
+ defaultTemperature: 0.0,
139
+ model: "gpt-4o-mini",
140
+ active: true,
141
+ };
142
+ await PsAiModel.create({
143
+ name: "GPT-4o Mini",
144
+ organization_id: 1,
145
+ user_id: userId,
146
+ configuration: openAiGpt4oMiniConfig,
147
+ });
148
+ console.log("Created OpenAI model: GPT-4o Mini");
149
+ }
150
+ else {
151
+ console.log("OpenAI model already exists: GPT-4o Mini");
152
+ }
153
+ // o1 Mini
154
+ const openAio1Mini = await PsAiModel.findOne({
155
+ where: { name: "o1 Mini" },
156
+ });
157
+ if (!openAio1Mini) {
158
+ const openAio1MiniConfig = {
159
+ type: PsAiModelType.TextReasoning,
160
+ modelSize: PsAiModelSize.Small,
161
+ provider: "openai",
162
+ prices: {
163
+ costInTokensPerMillion: 3.0,
164
+ costOutTokensPerMillion: 12.0,
165
+ currency: "USD",
166
+ },
167
+ maxTokensOut: 32000,
168
+ defaultTemperature: 0.0,
169
+ model: "o1-mini",
170
+ active: true,
171
+ };
172
+ await PsAiModel.create({
173
+ name: "o1 Mini",
174
+ organization_id: 1,
175
+ user_id: userId,
176
+ configuration: openAio1MiniConfig,
177
+ });
178
+ console.log("Created OpenAI model: o1 Mini");
179
+ }
180
+ else {
181
+ console.log("OpenAI model already exists: o1 Mini");
182
+ }
183
+ // o1 Preview
184
+ const openAio1Preview = await PsAiModel.findOne({
185
+ where: { name: "o1 Preview" },
186
+ });
187
+ if (!openAio1Preview) {
188
+ const openAio1PreviewConfig = {
189
+ type: PsAiModelType.TextReasoning,
190
+ modelSize: PsAiModelSize.Medium,
191
+ provider: "openai",
192
+ prices: {
193
+ costInTokensPerMillion: 15.0,
194
+ costOutTokensPerMillion: 60.0,
195
+ currency: "USD",
196
+ },
197
+ maxTokensOut: 32000,
198
+ defaultTemperature: 0.0,
199
+ model: "o1-preview",
200
+ active: true,
201
+ };
202
+ await PsAiModel.create({
203
+ name: "o1 Preview",
204
+ organization_id: 1,
205
+ user_id: userId,
206
+ configuration: openAio1PreviewConfig,
207
+ });
208
+ console.log("Created OpenAI model: o1 Preview");
209
+ }
210
+ else {
211
+ console.log("OpenAI model already exists: o1 Preview");
212
+ }
213
+ // o1 24
214
+ const openAio11712 = await PsAiModel.findOne({
215
+ where: { name: "o1 24" },
216
+ });
217
+ const openAio11712Config = {
218
+ type: PsAiModelType.TextReasoning,
219
+ modelSize: PsAiModelSize.Medium,
220
+ provider: "openai",
221
+ prices: {
222
+ costInTokensPerMillion: 15.0,
223
+ costOutTokensPerMillion: 60.0,
224
+ currency: "USD",
225
+ },
226
+ maxTokensOut: 100000,
227
+ defaultTemperature: 0.0,
228
+ model: "o1",
229
+ active: true,
230
+ };
231
+ if (!openAio11712) {
232
+ await PsAiModel.create({
233
+ name: "o1 24",
234
+ organization_id: 1,
235
+ user_id: userId,
236
+ configuration: openAio11712Config,
237
+ });
238
+ console.log("Created OpenAI model: o1 24");
239
+ }
240
+ else {
241
+ console.log("OpenAI model already exists: o1 24 updating");
242
+ openAio11712.set("configuration", openAio11712Config);
243
+ openAio11712.changed("configuration", true);
244
+ await openAio11712.save();
245
+ }
246
+ // o3 mini
247
+ const openAio3Mini = await PsAiModel.findOne({
248
+ where: { name: "o3 mini" },
249
+ });
250
+ if (!openAio3Mini) {
251
+ const openAio3MiniConfig = {
252
+ type: PsAiModelType.TextReasoning,
253
+ modelSize: PsAiModelSize.Small,
254
+ provider: "openai",
255
+ prices: {
256
+ costInTokensPerMillion: 1.1,
257
+ costOutTokensPerMillion: 4.4,
258
+ currency: "USD",
259
+ },
260
+ maxTokensOut: 100000,
261
+ defaultTemperature: 0.0,
262
+ model: "o3-mini",
263
+ active: true,
264
+ };
265
+ await PsAiModel.create({
266
+ name: "o3 mini",
267
+ organization_id: 1,
268
+ user_id: userId,
269
+ configuration: openAio3MiniConfig,
270
+ });
271
+ console.log("Created OpenAI model: o3 mini");
272
+ }
273
+ else {
274
+ console.log("OpenAI model already exists: o3 mini");
275
+ }
276
+ }
277
+ /**
278
+ * Seeds Google models.
279
+ * Currently, this creates Gemini 1.5 Pro 2 and Gemini 1.5 Flash 2.
280
+ */
281
+ static async seedGoogleModels(userId) {
282
+ // Gemini 1.5 Pro 2
283
+ const geminiPro = await PsAiModel.findOne({
284
+ where: { name: "Gemini 1.5 Pro 2" },
285
+ });
286
+ if (!geminiPro) {
287
+ const geminiProConfig = {
288
+ type: PsAiModelType.Text,
289
+ modelSize: PsAiModelSize.Medium,
290
+ provider: "google",
291
+ prices: {
292
+ costInTokensPerMillion: 1.25,
293
+ costOutTokensPerMillion: 5.0,
294
+ currency: "USD",
295
+ },
296
+ maxTokensOut: 8192,
297
+ defaultTemperature: 0.0,
298
+ model: "gemini-1.5-pro-002",
299
+ active: true,
300
+ };
301
+ await PsAiModel.create({
302
+ name: "Gemini 1.5 Pro 2",
303
+ organization_id: 1,
304
+ user_id: userId,
305
+ configuration: geminiProConfig,
306
+ });
307
+ console.log("Created Google model: Gemini 1.5 Pro 2");
308
+ }
309
+ else {
310
+ console.log("Google model already exists: Gemini 1.5 Pro 2");
311
+ }
312
+ // Gemini 1.5 Flash 2
313
+ const geminiPro15Flash = await PsAiModel.findOne({
314
+ where: { name: "Gemini 1.5 Flash 2" },
315
+ });
316
+ if (!geminiPro15Flash) {
317
+ const geminiPro15FlashConfig = {
318
+ type: PsAiModelType.Text,
319
+ modelSize: PsAiModelSize.Small,
320
+ provider: "google",
321
+ prices: {
322
+ costInTokensPerMillion: 0.075,
323
+ costOutTokensPerMillion: 0.3,
324
+ currency: "USD",
325
+ },
326
+ maxTokensOut: 8192,
327
+ defaultTemperature: 0.0,
328
+ model: "gemini-1.5-flash-002",
329
+ active: true,
330
+ };
331
+ await PsAiModel.create({
332
+ name: "Gemini 1.5 Flash 2",
333
+ organization_id: 1,
334
+ user_id: userId,
335
+ configuration: geminiPro15FlashConfig,
336
+ });
337
+ console.log("Created Google model: Gemini 1.5 Flash 2");
338
+ }
339
+ else {
340
+ console.log("Google model already exists: Gemini 1.5 Flash 2");
341
+ }
342
+ // Gemini 2.0 Flash
343
+ const gemini20Flash = await PsAiModel.findOne({
344
+ where: { name: "Gemini 2.0 Flash" },
345
+ });
346
+ if (!gemini20Flash) {
347
+ const gemini20FlashConfig = {
348
+ type: PsAiModelType.Text,
349
+ modelSize: PsAiModelSize.Medium,
350
+ provider: "google",
351
+ prices: {
352
+ costInTokensPerMillion: 0.1,
353
+ costOutTokensPerMillion: 0.4,
354
+ currency: "USD",
355
+ },
356
+ maxTokensOut: 8192,
357
+ defaultTemperature: 0.0,
358
+ model: "gemini-2.0-flash",
359
+ active: true,
360
+ };
361
+ await PsAiModel.create({
362
+ name: "Gemini 2.0 Flash",
363
+ organization_id: 1,
364
+ user_id: userId,
365
+ configuration: gemini20FlashConfig,
366
+ });
367
+ console.log("Created Google model: Gemini 2.0 Flash");
368
+ }
369
+ else {
370
+ console.log("Google model already exists: Gemini 2.0 Flash");
371
+ }
372
+ }
373
+ /**
374
+ * Master seeding function which calls the provider-specific functions
375
+ * and also seeds a top-level agent class.
376
+ */
377
+ static async seedAiModels(userId) {
378
+ try {
379
+ await NewAiModelSetup.seedAnthropicModels(userId);
380
+ await NewAiModelSetup.seedOpenAiModels(userId);
381
+ await NewAiModelSetup.seedGoogleModels(userId);
382
+ // Optionally, seed the top-level agent class if it does not exist.
383
+ const topLevelAgentClass = await PsAgentClass.findOne({
384
+ where: { name: "Operations" },
385
+ });
386
+ if (!topLevelAgentClass) {
387
+ const topLevelAgentClassConfig = {
388
+ category: PsAgentClassCategories.PolicySynthTopLevel,
389
+ subCategory: "group",
390
+ hasPublicAccess: true,
391
+ description: "A top-level agent that coordinates other agents",
392
+ queueName: "noqueue",
393
+ imageUrl: "https://yrpri-eu-direct-assets.s3.eu-west-1.amazonaws.com/topLevelAgent.png",
394
+ iconName: "coordinator",
395
+ capabilities: [
396
+ "process coordination",
397
+ "task management",
398
+ "result aggregation",
399
+ ],
400
+ questions: [],
401
+ requestedAiModelSizes: [
402
+ PsAiModelSize.Large,
403
+ PsAiModelSize.Medium,
404
+ PsAiModelSize.Small,
405
+ ],
406
+ supportedConnectors: [],
407
+ };
408
+ await PsAgentClass.create({
409
+ class_base_id: "c375c1fb-58ca-4372-a567-0e02b2c3d479",
410
+ name: "Operations",
411
+ version: 1,
412
+ available: true,
413
+ configuration: topLevelAgentClassConfig,
414
+ user_id: userId,
415
+ });
416
+ console.log("Created top-level agent class: Operations");
417
+ }
418
+ else {
419
+ console.log("Top-level agent class: Operations already exists");
420
+ }
421
+ }
422
+ catch (error) {
423
+ console.error("Error seeding AI models:", error);
424
+ process.exit(1);
425
+ }
426
+ }
427
+ /**
428
+ * Helper to delay model seeding slightly.
429
+ */
430
+ static setupAiModels(userId) {
431
+ setTimeout(async () => {
432
+ console.log("Seeding AI models");
433
+ await NewAiModelSetup.seedAiModels(userId);
434
+ }, 100);
435
+ }
436
+ /**
437
+ * Sets up the API keys for a given group based on the latest active AI models.
438
+ * @param group The group instance on which to set the API keys
439
+ */
440
+ static async setupApiKeysForGroup(group) {
441
+ // Helper to find the latest active model by name
442
+ const findLatestActiveModel = async (name) => {
443
+ return await PsAiModel.findOne({
444
+ where: {
445
+ name,
446
+ configuration: { active: true },
447
+ },
448
+ order: [["created_at", "DESC"]],
449
+ });
450
+ };
451
+ // Cache the API keys from environment variables
452
+ const apiKeys = {
453
+ ANTHROPIC_CLAUDE_API_KEY: process.env.ANTHROPIC_CLAUDE_API_KEY,
454
+ OPENAI_API_KEY: process.env.OPENAI_API_KEY,
455
+ GEMINI_API_KEY: process.env.GEMINI_API_KEY,
456
+ };
457
+ // Define a mapping between model names and their required API key
458
+ // Explicitly type envKey as a key of apiKeys
459
+ const modelsMapping = [
460
+ { name: "Anthropic Sonnet 3.5", envKey: "ANTHROPIC_CLAUDE_API_KEY" },
461
+ { name: "GPT-4o", envKey: "OPENAI_API_KEY" },
462
+ { name: "GPT-4o Mini", envKey: "OPENAI_API_KEY" },
463
+ { name: "o1 Preview", envKey: "OPENAI_API_KEY" },
464
+ { name: "o1 Mini", envKey: "OPENAI_API_KEY" },
465
+ { name: "Gemini 1.5 Pro 2", envKey: "GEMINI_API_KEY" },
466
+ { name: "Gemini 1.5 Flash 2", envKey: "GEMINI_API_KEY" },
467
+ { name: "Gemini 2.0 Flash", envKey: "GEMINI_API_KEY" },
468
+ { name: "o1 24", envKey: "OPENAI_API_KEY" },
469
+ { name: "o3 mini", envKey: "OPENAI_API_KEY" },
470
+ ];
471
+ const groupAccessConfig = [];
472
+ for (const { name, envKey } of modelsMapping) {
473
+ const apiKey = apiKeys[envKey];
474
+ if (!apiKey)
475
+ continue; // Skip if the API key is not provided
476
+ const model = await findLatestActiveModel(name);
477
+ if (model) {
478
+ groupAccessConfig.push({
479
+ aiModelId: model.id,
480
+ apiKey,
481
+ });
482
+ }
483
+ }
484
+ group.set("private_access_configuration", groupAccessConfig);
485
+ group.changed("private_access_configuration", true);
486
+ await group.save();
487
+ }
488
+ }