@yrpri/api 9.0.102 → 9.0.104

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 (223) hide show
  1. package/active-citizen/llms/imageGeneration/chatGptImageGenerator.js +56 -0
  2. package/active-citizen/llms/imageGeneration/collectionImageGenerator.js +6 -0
  3. package/agents/controllers/agentProductController.js +2 -1
  4. package/agents/controllers/agentSubscriptionController.js +20 -11
  5. package/agents/controllers/assistantsController.js +28 -18
  6. package/agents/controllers/policySynthAgents.js +33 -12
  7. package/agents/managers/newAiModelSetup.js +96 -0
  8. package/agents/managers/subscriptionManager.js +2 -2
  9. package/app.js +12 -12
  10. package/authorization.cjs +4 -0
  11. package/controllers/allOurIdeas.js +2 -1
  12. package/controllers/communities.cjs +47 -1
  13. package/controllers/groups.cjs +67 -4
  14. package/controllers/index.cjs +7 -7
  15. package/controllers/nonSpa.cjs +1 -1
  16. package/package.json +46 -44
  17. package/server.d.ts +104 -2
  18. package/utils/copy_utils.cjs +7 -1
  19. package/active-citizen/engine/allOurIdeas/aiHelper.d.ts +0 -21
  20. package/active-citizen/engine/allOurIdeas/aiHelper.d.ts.map +0 -1
  21. package/active-citizen/engine/allOurIdeas/explainAnswersAssistant.d.ts.map +0 -1
  22. package/active-citizen/engine/allOurIdeas/iconGenerator.d.ts +0 -12
  23. package/active-citizen/engine/allOurIdeas/iconGenerator.d.ts.map +0 -1
  24. package/active-citizen/engine/analytics/export_anon_community_activities.d.ts.map +0 -1
  25. package/active-citizen/engine/analytics/importer.d.ts.map +0 -1
  26. package/active-citizen/engine/old/exporters/categories_dataset.d.ts.map +0 -1
  27. package/active-citizen/engine/old/exporters/dataset_tools.d.ts.map +0 -1
  28. package/active-citizen/engine/old/exporters/sentiment_dataset.d.ts.map +0 -1
  29. package/active-citizen/engine/reports/xls_all_our_ideas_export.js +0 -141
  30. package/active-citizen/llms/baseChatBot.d.ts +0 -51
  31. package/active-citizen/llms/baseChatBot.d.ts.map +0 -1
  32. package/active-citizen/llms/collectionImageGenerator.js +0 -357
  33. package/active-citizen/llms/llmTranslation.d.ts +0 -24
  34. package/active-citizen/llms/llmTranslation.d.ts.map +0 -1
  35. package/active-citizen/scripts/fix_old_delayed_notifications.d.ts.map +0 -1
  36. package/active-citizen/scripts/kue_status.d.ts.map +0 -1
  37. package/active-citizen/scripts/kue_watch_stuck_jobs.d.ts.map +0 -1
  38. package/active-citizen/scripts/translation_clear_language.d.ts.map +0 -1
  39. package/active-citizen/scripts/translation_delete.d.ts.map +0 -1
  40. package/active-citizen/scripts/translation_replace_text_from_url.d.ts.map +0 -1
  41. package/active-citizen/scripts/translation_update.d.ts.map +0 -1
  42. package/active-citizen/scripts/translations_list.d.ts.map +0 -1
  43. package/active-citizen/utils/airbrake.d.ts.map +0 -1
  44. package/active-citizen/utils/airbrake.js +0 -17
  45. package/active-citizen/utils/updateAllLocalesFromEn.d.ts +0 -21
  46. package/active-citizen/utils/updateAllLocalesFromEn.d.ts.map +0 -1
  47. package/active-citizen/utils/updateLocaleFolders.d.ts +0 -2
  48. package/active-citizen/utils/updateLocaleFolders.d.ts.map +0 -1
  49. package/active-citizen/workers/cloudflare/voiceSession/worker.js +0 -213
  50. package/active-citizen/workers/generativeAi.d.ts.map +0 -1
  51. package/agents/agentProductManager.js +0 -91
  52. package/agents/assistants/agentAssistantOld.js +0 -863
  53. package/agents/assistants/modes/agentConfigurationMode.js +0 -63
  54. package/agents/assistants/modes/agentOperationsMode.js +0 -195
  55. package/agents/assistants/modes/commonTools.js +0 -58
  56. package/agents/assistants/modes/directConversationMode.js +0 -14
  57. package/agents/assistants/modes/toolHandlers/accountHandlers.js +0 -46
  58. package/agents/assistants/modes/toolHandlers/commonHandlers.js +0 -57
  59. package/agents/assistants/modes/toolHandlers/commonTools.js +0 -58
  60. package/agents/assistants/modes/toolHandlers/loginHandlers.js +0 -46
  61. package/agents/assistants/modes/toolHandlers/subscriptionHandlers.js +0 -469
  62. package/agents/assistants/modes/tools/agentConnectionTools.js +0 -326
  63. package/agents/assistants/modes/tools/commonHandlers.js +0 -57
  64. package/agents/assistants/modes/tools/loginHandlers.js +0 -46
  65. package/agents/assistants/modes/tools/subscriptionHandlers.js +0 -469
  66. package/agents/assistants/modes/tools/workflowConversationTools.js +0 -326
  67. package/agents/assistants/modes/tools/workflowTools.js +0 -112
  68. package/agents/controllers/assistantController.js +0 -243
  69. package/agents/managers/workflowManager.js +0 -76
  70. package/agents/models/testData/setupConfig.js +0 -140
  71. package/agents/models/workflow.js +0 -53
  72. package/agents/models/workflowConverstation.js +0 -53
  73. package/agents/subscriptionManager.js +0 -218
  74. package/agents/tools/updateCommunityWorkflow.js +0 -1
  75. package/agents/tools/updateTemplateWorkflow.js +0 -45
  76. package/app.d.ts +0 -40
  77. package/app.d.ts.map +0 -1
  78. package/bot_control.d.ts.map +0 -1
  79. package/migrations/200824_create_embeddings_and_org_update.cjs +0 -15
  80. package/migrations/270724_createUsersAndAdminsForClasses.cjs +0 -100
  81. package/publish.d.ts.map +0 -1
  82. package/repack.d.ts.map +0 -1
  83. package/scripts/addRatingUsersToGroup.d.ts.map +0 -1
  84. package/scripts/addUserToOrganization.d.ts.map +0 -1
  85. package/scripts/analyseRatingsForCommunity.d.ts.map +0 -1
  86. package/scripts/analyzeAndFixBrokenPointUsers.d.ts.map +0 -1
  87. package/scripts/analyzeEndorsementsByCountry.d.ts.map +0 -1
  88. package/scripts/analyzePostsForCommunity.d.ts.map +0 -1
  89. package/scripts/bulkStatusUpdates/listUpdates.d.ts.map +0 -1
  90. package/scripts/bulkStatusUpdates/mergeLatestPostsToUpdate.d.ts.map +0 -1
  91. package/scripts/bulkStatusUpdates/performUpdate.d.ts.map +0 -1
  92. package/scripts/bulkStatusUpdates/performUpdateForGroup.d.ts.map +0 -1
  93. package/scripts/bulkStatusUpdates/performUpdateForGroup.js +0 -125
  94. package/scripts/bulkStatusUpdates/performUpdateForStatus.d.ts.map +0 -1
  95. package/scripts/change/changeVideoAspectTo.d.ts.map +0 -1
  96. package/scripts/change/setDomainAdmin.cjs +0 -45
  97. package/scripts/changeCommunityGroupcount.d.ts.map +0 -1
  98. package/scripts/changeCommunityPostCount.d.ts.map +0 -1
  99. package/scripts/changeGroupPostCount.d.ts.map +0 -1
  100. package/scripts/changeLanguage.d.ts.map +0 -1
  101. package/scripts/changeOfficalStatus.d.ts.map +0 -1
  102. package/scripts/cleanups/deleteAnonNotifications.d.ts.map +0 -1
  103. package/scripts/cleanups/deleteAnonNotifications.js +0 -91
  104. package/scripts/cleanups/deleteLinkGroupsWithDeletedCommunities.d.ts.map +0 -1
  105. package/scripts/cleanups/removeAllUsersFromHiddenPublicGroup.d.ts.map +0 -1
  106. package/scripts/clearAllEndorsementInGroup.d.ts.map +0 -1
  107. package/scripts/cloning/clearUsersForCommunitiesFromUrl.d.ts.map +0 -1
  108. package/scripts/cloning/cloneFromUrlScript.d.ts.map +0 -1
  109. package/scripts/cloning/cloneWBFromUrlScriptAndCreateLinks.d.ts.map +0 -1
  110. package/scripts/cloning/cloneWBFromUrlScriptNoUsersOrPoints.d.ts.map +0 -1
  111. package/scripts/cloning/cloneWBSerbianFromUrlScriptAndCreateLinks.d.ts.map +0 -1
  112. package/scripts/cloning/copyCommunityConfigAndTranslationsFromURL.d.ts.map +0 -1
  113. package/scripts/cloning/copyCommunityOneGroupToDomainNoUsersNoEndorsements.d.ts.map +0 -1
  114. package/scripts/cloning/copyCommunityToDomainNoUsersNoEndorsements.d.ts.map +0 -1
  115. package/scripts/cloning/copyCommunityToDomainWithEverything.d.ts.map +0 -1
  116. package/scripts/cloning/copyCommunityToDomainWithOnlyGroups.d.ts.map +0 -1
  117. package/scripts/cloning/copyGroupConfigAndTranslationsFromURL.d.ts.map +0 -1
  118. package/scripts/cloning/copyPostToGroupOld.d.ts.map +0 -1
  119. package/scripts/cloning/copyPostVideosFromURL.d.ts.map +0 -1
  120. package/scripts/cloning/copyPostWithOutAnyVotingOrActivities.d.ts.map +0 -1
  121. package/scripts/cloning/deepCloneSerbianWBFromUrlScriptAndCreateLinks.d.ts.map +0 -1
  122. package/scripts/cloning/deepCloneWBFromUrlScriptAndCreateLinks.d.ts.map +0 -1
  123. package/scripts/cloning/setAdminsFromURL.d.ts.map +0 -1
  124. package/scripts/cloning/setExternalIdsFromURL.d.ts.map +0 -1
  125. package/scripts/countCommunity.d.ts.map +0 -1
  126. package/scripts/countCommunityUsers.d.ts.map +0 -1
  127. package/scripts/countDelayedNotifications.d.ts.map +0 -1
  128. package/scripts/countGroup.d.ts.map +0 -1
  129. package/scripts/countStuff.d.ts.map +0 -1
  130. package/scripts/countUniqueVotersInAGroup.d.ts.map +0 -1
  131. package/scripts/createInvitesAndShow.d.ts.map +0 -1
  132. package/scripts/database/seedTestAiModels.js +0 -64
  133. package/scripts/database/sync_database.d.ts.map +0 -1
  134. package/scripts/database/sync_dev_database.d.ts.map +0 -1
  135. package/scripts/debugNotifications.d.ts.map +0 -1
  136. package/scripts/deleteAllNewsFeeds.d.ts.map +0 -1
  137. package/scripts/deleteCategory.d.ts.map +0 -1
  138. package/scripts/deleteOldAppActivities.d.ts.map +0 -1
  139. package/scripts/deletePostContactDataForCommunity.d.ts.map +0 -1
  140. package/scripts/destroy/destroy_all_but_one_domain.d.ts.map +0 -1
  141. package/scripts/displayAuthorForPost.d.ts.map +0 -1
  142. package/scripts/endorsementFraudDetection/analyseEndorsementsForCommunity.d.ts.map +0 -1
  143. package/scripts/endorsementFraudDetection/bulkDeleteDuplicateEndorsmentsFromUrl.d.ts.map +0 -1
  144. package/scripts/exportAllStatusChanges.d.ts.map +0 -1
  145. package/scripts/exportClientAcitivity.d.ts.map +0 -1
  146. package/scripts/exportEndorsementsForCommunity.d.ts.map +0 -1
  147. package/scripts/exportPointQualitiesForCommunity.d.ts.map +0 -1
  148. package/scripts/exportPostsAndPointsForCommunity.d.ts.map +0 -1
  149. package/scripts/exportPostsDataSetForDomain.d.ts.map +0 -1
  150. package/scripts/exportPostsForGroup.d.ts.map +0 -1
  151. package/scripts/exportRatingsForPost.d.ts.map +0 -1
  152. package/scripts/exportUserEndorsementsWithUserAnalysis.d.ts.map +0 -1
  153. package/scripts/exportUsersForCommunity.d.ts.map +0 -1
  154. package/scripts/exportUsersForDomain.d.ts.map +0 -1
  155. package/scripts/exportUsersForGroup.d.ts.map +0 -1
  156. package/scripts/exports/ratingDistribution.d.ts.map +0 -1
  157. package/scripts/exports/whoEndorsedWhatByCommunity.d.ts.map +0 -1
  158. package/scripts/findUnusedClientImports.d.ts.map +0 -1
  159. package/scripts/fixAllPostPointCounts.d.ts.map +0 -1
  160. package/scripts/fixAnonNotificationsSettings.d.ts.map +0 -1
  161. package/scripts/fixCountKopavogur.d.ts.map +0 -1
  162. package/scripts/fixEndorsementsAfterCopyPostToGroup.d.ts.map +0 -1
  163. package/scripts/fixExternalUserId.d.ts.map +0 -1
  164. package/scripts/fixGroupAccess.d.ts.map +0 -1
  165. package/scripts/fixGroupIdeasAndPointsCount.d.ts.map +0 -1
  166. package/scripts/fixNotificationSettings.d.ts.map +0 -1
  167. package/scripts/fixSurveyRadioBakedInSubCodes.d.ts.map +0 -1
  168. package/scripts/fixWrongUserIdForStatusUpdates.d.ts.map +0 -1
  169. package/scripts/gallery/exportGalleryData.d.ts.map +0 -1
  170. package/scripts/gallery/importGalleryForCommunity.d.ts.map +0 -1
  171. package/scripts/gallery/readJsonAndDownloadImagesVersion2.d.ts.map +0 -1
  172. package/scripts/gallery/refreshAcApiPostIdsForCommunity.d.ts.map +0 -1
  173. package/scripts/genderAnalysis.d.ts.map +0 -1
  174. package/scripts/genderAnalysisByStatus.d.ts.map +0 -1
  175. package/scripts/importAllLocalesFromLocalFolders.d.ts.map +0 -1
  176. package/scripts/importDomain.d.ts.map +0 -1
  177. package/scripts/landUseGame/export3Ddata.d.ts.map +0 -1
  178. package/scripts/listLanguagesForGroup.d.ts.map +0 -1
  179. package/scripts/loadTestCreateDummyContentForGroup.d.ts.map +0 -1
  180. package/scripts/makeRecursiveMapData.d.ts.map +0 -1
  181. package/scripts/mapping/community_map_csv.d.ts.map +0 -1
  182. package/scripts/moveCommunityToDomain.d.ts.map +0 -1
  183. package/scripts/moveGroupToCommunity.d.ts.map +0 -1
  184. package/scripts/movePostToGroup.d.ts.map +0 -1
  185. package/scripts/movePostsToGroupsRecountGroupFromUrl.d.ts.map +0 -1
  186. package/scripts/oldMovePostToGroup.d.ts.map +0 -1
  187. package/scripts/processCsvForPdfUrls.d.ts.map +0 -1
  188. package/scripts/processCsvForTranslationAndToxicity.d.ts.map +0 -1
  189. package/scripts/recount/recount_recursive_communities.d.ts.map +0 -1
  190. package/scripts/recountALLCommunityGroupCounts.d.ts.map +0 -1
  191. package/scripts/recountAll.d.ts.map +0 -1
  192. package/scripts/recountCommunitesFromUrl.d.ts.map +0 -1
  193. package/scripts/recountCommunity.d.ts.map +0 -1
  194. package/scripts/recountGroup.d.ts.map +0 -1
  195. package/scripts/recountGroupNoUserChange.d.ts.map +0 -1
  196. package/scripts/resetAllEndorsementsForGroup.d.ts.map +0 -1
  197. package/scripts/resetEnTranslationForGroup.d.ts.map +0 -1
  198. package/scripts/setDomainLocales.d.ts.map +0 -1
  199. package/scripts/setLanguageOnGroupCommunitesFromUrl.d.ts.map +0 -1
  200. package/scripts/setMemberOfAll.d.ts.map +0 -1
  201. package/scripts/setNewUserForContentOfCommunity.d.ts.map +0 -1
  202. package/scripts/setOfficialStatusOnAllPostsForCommunity.d.ts.map +0 -1
  203. package/scripts/setUserOnAll.d.ts.map +0 -1
  204. package/scripts/showCategoryForGroup.d.ts.map +0 -1
  205. package/scripts/showOldActivityTypes.d.ts.map +0 -1
  206. package/scripts/showPostsMissingCategoryForGroup.d.ts.map +0 -1
  207. package/scripts/showStatuses.d.ts.map +0 -1
  208. package/scripts/showUniqueVotersInCommunity.d.ts.map +0 -1
  209. package/scripts/showUserAgentsAndIpsForEmails.d.ts.map +0 -1
  210. package/scripts/simpleExportForGroupsForCommunity.d.ts.map +0 -1
  211. package/scripts/simpleExportForPointsForCommunity.d.ts.map +0 -1
  212. package/scripts/simpleExportForPostsForCommunity.d.ts.map +0 -1
  213. package/scripts/testForEndorsments.d.ts.map +0 -1
  214. package/scripts/undeleteGroupAndAllContent.d.ts.map +0 -1
  215. package/scripts/undeletePost.d.ts.map +0 -1
  216. package/scripts/unlinkSsn.d.ts.map +0 -1
  217. package/scripts/updateFromAlthingi.d.ts.map +0 -1
  218. package/server.d.ts.map +0 -1
  219. package/utils/copyGroup.js +0 -246
  220. package/utils/loggerTs.d.ts +0 -4
  221. package/utils/loggerTs.d.ts.map +0 -1
  222. package/utils/ypLanguages.d.ts +0 -18
  223. package/utils/ypLanguages.d.ts.map +0 -1
@@ -0,0 +1,56 @@
1
+ // chatGptImageGenerator.ts
2
+ import { OpenAI } from "openai";
3
+ export class ChatGptImageGenerator {
4
+ constructor(openAiKey) {
5
+ this.maxRetryCount = 3;
6
+ // the SDK will fall back to process.env.OPENAI_API_KEY if nothing is passed
7
+ this.openAiKey = openAiKey;
8
+ }
9
+ /**
10
+ * Generates an image URL from a prompt using OpenAI’s gpt-image-1 model.
11
+ * The returned link remains live for ~60 minutes – be sure to download
12
+ * or cache it right away in the calling service.
13
+ */
14
+ async generateImageUrl(prompt, type = "logo") {
15
+ const client = new OpenAI({ apiKey: this.openAiKey });
16
+ // Pick a sensible canvas size from the image type
17
+ let size = "1536x1024";
18
+ if (type === "icon")
19
+ size = "1024x1024";
20
+ else if (type === "other")
21
+ size = "1536x1024";
22
+ const finalPrompt = `
23
+ ${prompt}
24
+
25
+ Instruction: Create a high quality logo like image for the users project and follow their style instructions. \
26
+ Do not add text to the images unless asked in the style instructions.
27
+ `;
28
+ let retryCount = 0;
29
+ while (retryCount < this.maxRetryCount) {
30
+ try {
31
+ const res = await client.images.generate({
32
+ model: "gpt-image-1",
33
+ prompt: finalPrompt,
34
+ quality: "medium",
35
+ n: 1,
36
+ size
37
+ });
38
+ const url = res?.data?.[0]?.url;
39
+ if (url)
40
+ return url;
41
+ throw new Error("No URL returned");
42
+ }
43
+ catch (err) {
44
+ retryCount += 1;
45
+ if (retryCount >= this.maxRetryCount) {
46
+ console.error(`ChatGptImageGenerator failed after ${retryCount} attempts`, err);
47
+ return undefined;
48
+ }
49
+ // Exponential back-off – starts at 5 s and grows +5 s each retry
50
+ await new Promise((r) => setTimeout(r, 5000 + retryCount * 5000));
51
+ }
52
+ }
53
+ return undefined;
54
+ }
55
+ }
56
+ export default ChatGptImageGenerator;
@@ -9,6 +9,7 @@ import { S3Service } from "./s3Service.js";
9
9
  // Suppose these come from your codebase
10
10
  import models from "../../../models/index.cjs";
11
11
  import { ImagenImageGenerator } from "./imagenImageGenerator.js";
12
+ import { ChatGptImageGenerator } from "./chatGptImageGenerator.js";
12
13
  // For reference, in your code:
13
14
  const dbModels = models;
14
15
  const Image = dbModels.Image;
@@ -26,6 +27,7 @@ export class CollectionImageGenerator {
26
27
  this.fluxImageGenerator = new FluxImageGenerator(process.env.REPLICATE_API_TOKEN, process.env.FLUX_PRO_MODEL_NAME);
27
28
  }
28
29
  this.dalleImageGenerator = new DalleImageGenerator(process.env.AZURE_OPENAI_API_BASE, process.env.AZURE_OPENAI_API_KEY, process.env.AZURE_OPENAI_API_DALLE_DEPLOYMENT_NAME, process.env.OPENAI_API_KEY);
30
+ this.chatGptImageGenerator = new ChatGptImageGenerator(process.env.OPENAI_API_KEY);
29
31
  if (useImagen && process.env.GOOGLE_CLOUD_PROJECT_ID) {
30
32
  this.imagenImageGenerator = new ImagenImageGenerator(this.s3Service);
31
33
  }
@@ -50,6 +52,10 @@ export class CollectionImageGenerator {
50
52
  imageGenerator = this.fluxImageGenerator;
51
53
  console.info("Using FluxImageGenerator");
52
54
  }
55
+ else if (process.env.USE_CHATGPT_IMAGE_GENERATOR) {
56
+ imageGenerator = this.chatGptImageGenerator;
57
+ console.info("Using ChatGptImageGenerator");
58
+ }
53
59
  else {
54
60
  imageGenerator = this.dalleImageGenerator;
55
61
  console.info("Using DalleImageGenerator");
@@ -22,7 +22,8 @@ export class AgentProductController {
22
22
  const agentProductId = parseInt(req.params.agentProductId);
23
23
  const agentProduct = await this.agentProductManager.getAgentProduct(agentProductId);
24
24
  if (!agentProduct) {
25
- return res.status(404).json({ error: 'Agent product not found' });
25
+ res.status(404).json({ error: 'Agent product not found' });
26
+ return;
26
27
  }
27
28
  res.json(agentProduct);
28
29
  }
@@ -21,22 +21,25 @@ export class AgentSubscriptionController {
21
21
  },
22
22
  });
23
23
  if (!subscription) {
24
- return res.status(404).json({ error: "Subscription not found" });
24
+ res.status(404).json({ error: "Subscription not found" });
25
+ return;
25
26
  }
26
27
  // Extract the requiredQuestionsAnswered from subscription.configuration
27
28
  const answers = subscription.configuration?.requiredQuestionsAnswered || [];
28
- return res.status(200).json({
29
+ res.status(200).json({
29
30
  success: true,
30
31
  data: answers,
31
32
  });
33
+ return;
32
34
  }
33
35
  else {
34
- return res.status(401).json({ error: "Unauthorized" });
36
+ res.status(401).json({ error: "Unauthorized" });
37
+ return;
35
38
  }
36
39
  }
37
40
  catch (error) {
38
41
  console.error("Error retrieving subscription agent configuration:", error);
39
- return res.status(500).json({ error: error.message });
42
+ res.status(500).json({ error: error.message });
40
43
  }
41
44
  };
42
45
  this.updateAgentConfiguration = async (req, res) => {
@@ -44,13 +47,15 @@ export class AgentSubscriptionController {
44
47
  const subscriptionId = parseInt(req.params.subscriptionId);
45
48
  const requiredQuestionsAnswered = req.body.requiredQuestionsAnswered;
46
49
  if (!requiredQuestionsAnswered) {
47
- return res.status(400).json({ error: "requiredQuestionsAnswered is required" });
50
+ res.status(400).json({ error: "requiredQuestionsAnswered is required" });
51
+ return;
48
52
  }
49
53
  const subscription = await YpSubscription.findOne({
50
54
  where: { id: subscriptionId, user_id: req.user.id }
51
55
  });
52
56
  if (!subscription) {
53
- return res.status(404).json({ error: "Subscription not found" });
57
+ res.status(404).json({ error: "Subscription not found" });
58
+ return;
54
59
  }
55
60
  subscription.configuration.requiredQuestionsAnswered = JSON.parse(requiredQuestionsAnswered);
56
61
  subscription.changed('configuration', true);
@@ -78,13 +83,13 @@ export class AgentSubscriptionController {
78
83
  const userId = req.user.id;
79
84
  // If not a free trial request, redirect to payment intent endpoint
80
85
  if (!isFreeTrialRequest) {
81
- return res.status(400).json({
86
+ res.status(400).json({
82
87
  error: "For paid subscriptions, please use /stripe-create-payment-intent instead",
83
88
  });
84
89
  }
85
90
  // Handle free trial subscription
86
91
  if (!planIds) {
87
- return res.status(400).json({
92
+ res.status(400).json({
88
93
  error: "agentProductIds and planIds are required",
89
94
  });
90
95
  }
@@ -146,7 +151,8 @@ export class AgentSubscriptionController {
146
151
  where: { id: subscriptionId, user_id: userId },
147
152
  });
148
153
  if (!subscription) {
149
- return res.status(404).json({ error: "Subscription not found" });
154
+ res.status(404).json({ error: "Subscription not found" });
155
+ return;
150
156
  }
151
157
  subscription.status = "cancelled";
152
158
  await subscription.save();
@@ -166,7 +172,8 @@ export class AgentSubscriptionController {
166
172
  where: { id: subscriptionId, user_id: userId },
167
173
  });
168
174
  if (!subscription) {
169
- return res.status(404).json({ error: "Subscription not found" });
175
+ res.status(404).json({ error: "Subscription not found" });
176
+ return;
170
177
  }
171
178
  // Apply updates (validate as necessary)
172
179
  Object.assign(subscription, updates);
@@ -183,15 +190,17 @@ export class AgentSubscriptionController {
183
190
  const userId = req.user.id;
184
191
  const { planIds, paymentMethodId } = req.body;
185
192
  if (!planIds || !paymentMethodId) {
186
- return res.status(400).json({
193
+ res.status(400).json({
187
194
  error: "planIds, and paymentMethodId are required",
188
195
  });
196
+ return;
189
197
  }
190
198
  const result = await this.subscriptionManager.createSubscriptions(userId, planIds, paymentMethodId);
191
199
  res.status(200).json({
192
200
  clientSecret: result.clientSecret,
193
201
  subscriptionId: result.subscriptionId,
194
202
  });
203
+ return;
195
204
  }
196
205
  catch (error) {
197
206
  console.error("Error creating payment intent:", error);
@@ -53,28 +53,33 @@ export class AssistantController {
53
53
  const { agentId } = req.params;
54
54
  let lastStatusMessage = await this.getLastStatusMessageFromDB(parseInt(agentId));
55
55
  if (!lastStatusMessage) {
56
- return res.status(404).send("No status message found.");
56
+ res.status(404).send("No status message found.");
57
57
  }
58
58
  const regex = /<markdownReport>([\s\S]*?)<\/markdownReport>/i;
59
- const match = lastStatusMessage.match(regex);
59
+ const match = lastStatusMessage ? lastStatusMessage.match(regex) : null;
60
60
  console.debug(`match: ${JSON.stringify(match, null, 2)}`);
61
61
  if (!match || match.length < 2) {
62
62
  console.error("No <markdownReport>...</markdownReport> content found.");
63
- return res
63
+ res
64
64
  .status(400)
65
65
  .send("No <markdownReport>...</markdownReport> content found.");
66
66
  }
67
- const markdownContent = match[1];
67
+ const markdownContent = match ? match[1] : null;
68
+ if (!markdownContent) {
69
+ console.error("No markdown content found.");
70
+ res.status(400).send("No markdown content found.");
71
+ return;
72
+ }
68
73
  const htmlContent = await marked(markdownContent);
69
74
  const docxBuffer = (await HTMLtoDOCX(htmlContent));
70
75
  console.debug(`docxBuffer: ${docxBuffer.length}`);
71
76
  res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
72
77
  res.setHeader("Content-disposition", 'attachment; filename="converted.docx"');
73
- return res.send(docxBuffer);
78
+ res.send(docxBuffer);
74
79
  }
75
80
  catch (error) {
76
81
  console.error("Error converting Markdown to DOCX:", error);
77
- return res.status(500).send("Server error");
82
+ res.status(500).send("Server error");
78
83
  }
79
84
  };
80
85
  this.advanceOrStopCurrentWorkflowStep = async (req, res) => {
@@ -115,7 +120,8 @@ export class AssistantController {
115
120
  this.getAgentConfigurationAnswers = async (req, res) => {
116
121
  try {
117
122
  if (!req.user) {
118
- return res.status(401).json({ error: "Unauthorized" });
123
+ res.status(401).json({ error: "Unauthorized" });
124
+ return;
119
125
  }
120
126
  const subscriptionId = parseInt(req.params.subscriptionId);
121
127
  // Make sure the user can only fetch their own subscription
@@ -126,25 +132,26 @@ export class AssistantController {
126
132
  },
127
133
  });
128
134
  if (!subscription) {
129
- return res.status(404).json({ error: "Subscription not found" });
135
+ res.status(404).json({ error: "Subscription not found" });
130
136
  }
131
137
  // Extract the requiredQuestionsAnswered from subscription.configuration
132
- const answers = subscription.configuration?.requiredQuestionsAnswered || [];
133
- return res.status(200).json({
138
+ const answers = subscription?.configuration?.requiredQuestionsAnswered || [];
139
+ res.status(200).json({
134
140
  success: true,
135
141
  data: answers,
136
142
  });
137
143
  }
138
144
  catch (error) {
139
145
  console.error("Error retrieving subscription agent configuration:", error);
140
- return res.status(500).json({ error: error.message });
146
+ res.status(500).json({ error: error.message });
141
147
  }
142
148
  };
143
149
  this.getUpdatedWorkflow = async (req, res) => {
144
150
  const { runId } = req.params;
145
151
  const userId = req.user?.id;
146
152
  if (!userId) {
147
- return res.status(401).json({ error: "Unauthorized" });
153
+ res.status(401).json({ error: "Unauthorized" });
154
+ return;
148
155
  }
149
156
  try {
150
157
  const agentRun = await YpAgentProductRun.findOne({
@@ -208,13 +215,13 @@ export class AssistantController {
208
215
  catch (error) {
209
216
  console.error("Error saving subscription:", error);
210
217
  res.sendStatus(500);
211
- return;
212
218
  }
213
219
  res.sendStatus(200);
214
220
  };
215
221
  this.updateAssistantMemoryLoginStatus = async (req, res) => {
216
222
  if (!req.user) {
217
- return res.status(401).json({ error: "Unauthorized" });
223
+ res.status(401).json({ error: "Unauthorized" });
224
+ return;
218
225
  }
219
226
  try {
220
227
  const memory = await this.loadMemoryWithOwnership(req, res);
@@ -275,12 +282,13 @@ export class AssistantController {
275
282
  if (!memory)
276
283
  return;
277
284
  console.log(`Getting memory at key: ${memory.redisKey}`);
278
- return res.json(memory);
285
+ res.json(memory);
279
286
  };
280
287
  // New API endpoints for workflow management
281
288
  this.getRunningWorkflowConversations = async (req, res) => {
282
289
  if (!req.user || !req.user.id) {
283
- return res.status(401).json({ error: "Unauthorized" });
290
+ res.status(401).json({ error: "Unauthorized" });
291
+ return;
284
292
  }
285
293
  try {
286
294
  const workflows = await this.workflowConversationManager.getRunningWorkflowConversationsForUser(req.user.id);
@@ -297,7 +305,8 @@ export class AssistantController {
297
305
  };
298
306
  this.getAllWorkflowConversations = async (req, res) => {
299
307
  if (!req.user || !req.user.id) {
300
- return res.status(401).json({ error: "Unauthorized" });
308
+ res.status(401).json({ error: "Unauthorized" });
309
+ return;
301
310
  }
302
311
  try {
303
312
  const workflows = await this.workflowConversationManager.getWorkflowConversationsForUser(req.user.id);
@@ -314,7 +323,8 @@ export class AssistantController {
314
323
  };
315
324
  this.connectToWorkflowConversation = async (req, res) => {
316
325
  if (!req.user || !req.user.id) {
317
- return res.status(401).json({ error: "Unauthorized" });
326
+ res.status(401).json({ error: "Unauthorized" });
327
+ return;
318
328
  }
319
329
  try {
320
330
  const { workflowConversationId, connectionData } = req.body;
@@ -22,23 +22,24 @@ export class PolicySynthAgentsController {
22
22
  console.log(`Attempting to replace memory for agent ${agentId} in group ${groupId}`);
23
23
  if (!memory || Object.keys(memory).length === 0) {
24
24
  console.log(`Received empty memory for agent ${agentId}`);
25
- return res.status(400).json({ error: "Cannot save empty memory" });
25
+ res.status(400).json({ error: "Cannot save empty memory" });
26
+ return;
26
27
  }
27
28
  try {
28
29
  JSON.parse(JSON.stringify(memory));
29
30
  }
30
31
  catch (jsonError) {
31
32
  console.log(`Received invalid JSON for agent ${agentId}`);
32
- return res
33
- .status(400)
34
- .json({ error: "Invalid JSON format for memory" });
33
+ res.status(400).json({ error: "Invalid JSON format for memory" });
34
+ return;
35
35
  }
36
36
  const memoryKey = await this.agentManager.getSubAgentMemoryKey(groupId, parseInt(agentId));
37
37
  if (!memoryKey) {
38
38
  console.log(`Memory key not found for agent ${agentId}`);
39
- return res
39
+ res
40
40
  .status(404)
41
41
  .json({ error: "Memory key not found for the specified agent" });
42
+ return;
42
43
  }
43
44
  console.log(`Memory key found: ${memoryKey}`);
44
45
  await req.redisClient.set(memoryKey, JSON.stringify(memory));
@@ -53,15 +54,29 @@ export class PolicySynthAgentsController {
53
54
  else {
54
55
  res.status(500).json({ error: "An unexpected error occurred" });
55
56
  }
57
+ return;
56
58
  }
57
59
  };
58
60
  this.addExistingConnector = async (req, res) => {
59
- const { groupId, agentId, type } = req.params;
61
+ const { groupId, agentId } = req.params;
60
62
  const { connectorId } = req.body;
63
+ let type;
64
+ if (req.path.includes("/inputConnectors/")) {
65
+ type = "input";
66
+ }
67
+ else if (req.path.includes("/outputConnectors/")) {
68
+ type = "output";
69
+ }
70
+ else {
71
+ // This case should ideally not be reached if routes are set up correctly
72
+ res.status(400).send("Could not determine connector type from path");
73
+ return;
74
+ }
61
75
  if (!groupId || !agentId || !connectorId) {
62
- return res
76
+ res
63
77
  .status(400)
64
78
  .send("Group ID, agent ID and connector ID (input/output) are required");
79
+ return;
65
80
  }
66
81
  try {
67
82
  await this.agentConnectorManager.addExistingConnector(parseInt(groupId), parseInt(agentId), parseInt(connectorId), type);
@@ -86,15 +101,17 @@ export class PolicySynthAgentsController {
86
101
  const memoryKey = await this.agentManager.getSubAgentMemoryKey(groupId, parseInt(agentId));
87
102
  if (!memoryKey) {
88
103
  console.log(`Memory key not found for agent ${agentId}`);
89
- return res
104
+ res
90
105
  .status(404)
91
106
  .json({ error: "Memory key not found for the specified agent" });
107
+ return;
92
108
  }
93
109
  console.log(`Memory key found: ${memoryKey}`);
94
110
  const memoryContents = await req.redisClient.get(memoryKey);
95
111
  if (!memoryContents) {
96
112
  console.log(`Memory contents not found for key ${memoryKey}`);
97
- return res.status(404).json({ error: "Memory contents not found" });
113
+ res.status(404).json({ error: "Memory contents not found" });
114
+ return;
98
115
  }
99
116
  console.log(`Memory contents retrieved successfully`);
100
117
  const parsedMemoryContents = JSON.parse(memoryContents);
@@ -108,6 +125,7 @@ export class PolicySynthAgentsController {
108
125
  else {
109
126
  res.status(500).json({ error: "An unexpected error occurred" });
110
127
  }
128
+ return;
111
129
  }
112
130
  };
113
131
  this.getAgent = async (req, res) => {
@@ -118,6 +136,7 @@ export class PolicySynthAgentsController {
118
136
  catch (error) {
119
137
  console.error("Error in getAgent:", error);
120
138
  res.status(500).send("Internal Server Error");
139
+ return;
121
140
  }
122
141
  };
123
142
  this.getAgentAiModels = async (req, res) => {
@@ -163,13 +182,15 @@ export class PolicySynthAgentsController {
163
182
  await this.agentConnectorManager.updateConnectorConfiguration(nodeId, updatedConfig);
164
183
  }
165
184
  else {
166
- return res.status(400).send("Invalid node type");
185
+ res.status(400).send("Invalid node type");
186
+ return;
167
187
  }
168
188
  res.json({ message: `${nodeType} configuration updated successfully` });
169
189
  }
170
190
  catch (error) {
171
191
  console.error(`Error updating ${nodeType} configuration:`, error);
172
192
  res.status(500).send("Internal Server Error");
193
+ return;
173
194
  }
174
195
  };
175
196
  this.createInputConnector = async (req, res) => {
@@ -388,8 +409,8 @@ export class PolicySynthAgentsController {
388
409
  this.router.get("/:groupId/:id/ai-models", auth.can("view group"), this.getAgentAiModels);
389
410
  this.router.delete("/:groupId/:agentId/ai-models/:modelId", auth.can("edit group"), this.removeAgentAiModel);
390
411
  this.router.post("/:groupId/:agentId/ai-models", auth.can("edit group"), this.addAgentAiModel);
391
- this.router.get("/:groupId/:agentId/memory", auth.can("view group"), this.getAgentMemory);
392
412
  this.router.put("/:groupId/:agentId/memory", auth.can("edit group"), this.replaceAgentMemory);
393
- this.router.post("/:groupId/:agentId/:type(input|output)Connectors/existing", auth.can("edit group"), this.addExistingConnector);
413
+ this.router.post("/:groupId/:agentId/inputConnectors/existing", auth.can("edit group"), this.addExistingConnector);
414
+ this.router.post("/:groupId/:agentId/outputConnectors/existing", auth.can("edit group"), this.addExistingConnector);
394
415
  }
395
416
  }
@@ -336,6 +336,99 @@ export class NewAiModelSetup {
336
336
  else {
337
337
  console.log("OpenAI model already exists: GPT-4.5 Preview updating");
338
338
  }
339
+ const openAio3 = await PsAiModel.findOne({
340
+ where: { name: "o3" },
341
+ });
342
+ const openAio3Config = {
343
+ type: PsAiModelType.TextReasoning,
344
+ modelSize: PsAiModelSize.Medium,
345
+ provider: "openai",
346
+ prices: {
347
+ costInTokensPerMillion: 10.0,
348
+ costOutTokensPerMillion: 40.0,
349
+ cacheCostInTokensPerMillion: 2.5,
350
+ currency: "USD",
351
+ },
352
+ maxTokensOut: 100000,
353
+ defaultTemperature: 0.0,
354
+ model: "o3",
355
+ active: true,
356
+ };
357
+ if (!openAio3) {
358
+ await PsAiModel.create({
359
+ name: "o3",
360
+ organization_id: 1,
361
+ user_id: userId,
362
+ configuration: openAio3Config,
363
+ });
364
+ console.log("Created OpenAI model: o3");
365
+ }
366
+ else {
367
+ console.log("OpenAI model already exists: o3 updating");
368
+ openAio3.set("configuration", openAio3Config);
369
+ openAio3.changed("configuration", true);
370
+ await openAio3.save();
371
+ }
372
+ const openAio4mini = await PsAiModel.findOne({
373
+ where: { name: "o4 mini" },
374
+ });
375
+ const openAio4miniConfig = {
376
+ type: PsAiModelType.TextReasoning,
377
+ modelSize: PsAiModelSize.Small,
378
+ provider: "openai",
379
+ prices: {
380
+ costInTokensPerMillion: 1.1,
381
+ costOutTokensPerMillion: 4.4,
382
+ cacheCostInTokensPerMillion: 0.275,
383
+ currency: "USD",
384
+ },
385
+ maxTokensOut: 100000,
386
+ defaultTemperature: 0.0,
387
+ model: "o4-mini",
388
+ active: true,
389
+ };
390
+ if (!openAio4mini) {
391
+ await PsAiModel.create({
392
+ name: "o4 mini",
393
+ organization_id: 1,
394
+ user_id: userId,
395
+ configuration: openAio4miniConfig,
396
+ });
397
+ console.log("Created OpenAI model: o4 mini");
398
+ }
399
+ else {
400
+ console.log("OpenAI model already exists: o4 mini");
401
+ }
402
+ const openAiGpt41 = await PsAiModel.findOne({
403
+ where: { name: "GPT-4.1" },
404
+ });
405
+ const openAiGpt41Config = {
406
+ type: PsAiModelType.Text,
407
+ modelSize: PsAiModelSize.Medium,
408
+ provider: "openai",
409
+ prices: {
410
+ costInTokensPerMillion: 2,
411
+ costOutTokensPerMillion: 8,
412
+ currency: "USD",
413
+ cacheCostInTokensPerMillion: 0.5
414
+ },
415
+ maxTokensOut: 100000,
416
+ defaultTemperature: 0.7,
417
+ model: "gpt-4.1",
418
+ active: true,
419
+ };
420
+ if (!openAiGpt41) {
421
+ await PsAiModel.create({
422
+ name: "GPT-4.1",
423
+ organization_id: 1,
424
+ user_id: userId,
425
+ configuration: openAiGpt41Config,
426
+ });
427
+ console.log("Created OpenAI model: GPT-4.1");
428
+ }
429
+ else {
430
+ console.log("OpenAI model already exists: GPT-4.1");
431
+ }
339
432
  }
340
433
  /**
341
434
  * Seeds Google models.
@@ -533,6 +626,9 @@ export class NewAiModelSetup {
533
626
  { name: "Gemini 2.0 Flash", envKey: "GEMINI_API_KEY" },
534
627
  { name: "o1 24", envKey: "OPENAI_API_KEY" },
535
628
  { name: "o3 mini", envKey: "OPENAI_API_KEY" },
629
+ { name: "o4 mini", envKey: "OPENAI_API_KEY" },
630
+ { name: "GPT-4.1", envKey: "OPENAI_API_KEY" },
631
+ { name: "o3", envKey: "OPENAI_API_KEY" },
536
632
  ];
537
633
  const groupAccessConfig = [];
538
634
  for (const { name, envKey } of modelsMapping) {
@@ -321,7 +321,7 @@ export class SubscriptionManager {
321
321
  return { freeSubscription: true };
322
322
  }
323
323
  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
324
- apiVersion: "2025-01-27.acacia",
324
+ apiVersion: "2025-04-30.basil",
325
325
  });
326
326
  // Create a PaymentIntent with Stripe
327
327
  const paymentIntent = await stripe.paymentIntents.create({
@@ -359,7 +359,7 @@ export class SubscriptionManager {
359
359
  async handleSuccessfulPayment(paymentIntentId) {
360
360
  try {
361
361
  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
362
- apiVersion: "2025-01-27.acacia",
362
+ apiVersion: "2025-04-30.basil",
363
363
  });
364
364
  const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
365
365
  if (paymentIntent.status !== "succeeded") {
package/app.js CHANGED
@@ -559,19 +559,19 @@ export class YourPrioritiesApi {
559
559
  // Promotion app
560
560
  const promotionAppPath = path.join(baseDir, "old/promotion_app/dist");
561
561
  this.app.use("/promotion", express.static(promotionAppPath));
562
- this.app.use("/promotion/domain/*", express.static(promotionAppPath));
563
- this.app.use("/promotion/organization/*", express.static(promotionAppPath));
564
- this.app.use("/promotion/community/*", express.static(promotionAppPath));
565
- this.app.use("/promotion/group/*", express.static(promotionAppPath));
566
- this.app.use("/promotion/post/*", express.static(promotionAppPath));
567
- this.app.use("/promotion/locales/en/*", express.static(path.join(promotionAppPath, "locales/en")));
568
- this.app.use("/promotion/locales/is/*", express.static(path.join(promotionAppPath, "locales/is")));
562
+ this.app.use("/promotion/domain/*splat", express.static(promotionAppPath));
563
+ this.app.use("/promotion/organization/*splat", express.static(promotionAppPath));
564
+ this.app.use("/promotion/community/*splat", express.static(promotionAppPath));
565
+ this.app.use("/promotion/group/*splat", express.static(promotionAppPath));
566
+ this.app.use("/promotion/post/*splat", express.static(promotionAppPath));
567
+ this.app.use("/promotion/locales/en/*splat", express.static(path.join(promotionAppPath, "locales/en")));
568
+ this.app.use("/promotion/locales/is/*splat", express.static(path.join(promotionAppPath, "locales/is")));
569
569
  // Land use game
570
570
  const landUseGamePath = path.join(baseDir, "land_use_game/dist");
571
571
  this.app.use("/land_use", express.static(landUseGamePath));
572
- this.app.use("/land_use/*", express.static(landUseGamePath));
573
- this.app.use("/land_use/locales/en/*", express.static(path.join(landUseGamePath, "locales/en")));
574
- this.app.use("/land_use/locales/is/*", express.static(path.join(landUseGamePath, "locales/is")));
572
+ this.app.use("/land_use/*splat", express.static(landUseGamePath));
573
+ this.app.use("/land_use/locales/en/*splat", express.static(path.join(landUseGamePath, "locales/en")));
574
+ this.app.use("/land_use/locales/is/*splat", express.static(path.join(landUseGamePath, "locales/is")));
575
575
  this.app.use("/Assets", express.static(path.join(landUseGamePath, "Assets")));
576
576
  this.app.use("/ThirdParty", express.static(path.join(landUseGamePath, "ThirdParty")));
577
577
  this.app.use("/Widgets", express.static(path.join(landUseGamePath, "Widgets")));
@@ -606,12 +606,12 @@ export class YourPrioritiesApi {
606
606
  this.app.use("/domain", index);
607
607
  this.app.use("/community", index);
608
608
  this.app.use("/organization", index);
609
- this.app.use("/agent_bundle/*", index);
609
+ this.app.use("/agent_bundle/*splat", index);
610
610
  this.app.use("/group", index);
611
611
  this.app.use("/post", index);
612
612
  this.app.use("/user", index);
613
613
  this.app.use("/admin", index);
614
- this.app.use("/survey*", index);
614
+ this.app.use('/survey*splat', index);
615
615
  this.app.use("/api/domains", domains);
616
616
  this.app.use("/api/organizations", organizations);
617
617
  this.app.use("/api/communities", communities);
package/authorization.cjs CHANGED
@@ -546,6 +546,10 @@ auth.entity("domain", function (req, done) {
546
546
  var match = req.originalUrl.match(/domains\/(\w+)/);
547
547
  if (!match)
548
548
  match = req.originalUrl.match(/videos\/(\w+)/);
549
+ if (!match)
550
+ match = req.originalUrl.match(/communities\/(\w+)/);
551
+ if (!match)
552
+ match = req.originalUrl.match(/groups\/(\w+)/);
549
553
  if (!match)
550
554
  match = req.originalUrl.match(/images\/(\w+)/);
551
555
  if (!match)
@@ -378,7 +378,8 @@ export class AllOurIdeasController {
378
378
  const questionParams = req.body;
379
379
  console.log(`in createQuestion: ${JSON.stringify(questionParams.ideas)}`);
380
380
  if (questionParams.ideas.length < 4) {
381
- return res.status(400).json({ error: "Invalid input" });
381
+ res.status(400).json({ error: "Invalid input" });
382
+ return;
382
383
  }
383
384
  const requestBody = {
384
385
  name: questionParams.question,