@yrpri/api 9.0.142 → 9.0.144

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,12 @@
1
+ import WebSocket from "ws";
2
+ export declare class AgentTaskController {
3
+ path: string;
4
+ router: import("express-serve-static-core").Router;
5
+ private taskManager;
6
+ constructor(wsClients: Map<string, WebSocket>);
7
+ private initializeRoutes;
8
+ private startTask;
9
+ private stopTask;
10
+ private agentStatus;
11
+ private getAgentMemory;
12
+ }
@@ -0,0 +1,72 @@
1
+ import express from "express";
2
+ import auth from "../../authorization.cjs";
3
+ import { TaskManager } from "../tasks/taskManager.js";
4
+ import log from "../../utils/loggerTs.js";
5
+ export class AgentTaskController {
6
+ constructor(wsClients) {
7
+ this.path = "/api/agentTasks";
8
+ this.router = express.Router();
9
+ this.startTask = async (req, res) => {
10
+ try {
11
+ const { communityIdToClone } = req.body;
12
+ const domainId = parseInt(req.params.domainId);
13
+ const agentId = await this.taskManager.startTask(communityIdToClone, domainId, req.user);
14
+ res.status(200).json({ agentId });
15
+ }
16
+ catch (error) {
17
+ log.error("Error starting task:", error);
18
+ res.status(500).json({ error: error.message });
19
+ }
20
+ };
21
+ this.stopTask = async (req, res) => {
22
+ try {
23
+ const { agentId, agentRunId, wsClientId } = req.body;
24
+ await this.taskManager.stopTask(agentId, agentRunId, wsClientId);
25
+ res.sendStatus(200);
26
+ }
27
+ catch (error) {
28
+ log.error("Error stopping task:", error);
29
+ res.status(500).json({ error: error.message });
30
+ }
31
+ };
32
+ this.agentStatus = async (req, res) => {
33
+ try {
34
+ const agentId = parseInt(req.params.agentId);
35
+ const status = await this.taskManager.agentStatus(agentId);
36
+ if (status) {
37
+ res.json(status);
38
+ }
39
+ else {
40
+ res.status(404).send("Agent status not found");
41
+ }
42
+ }
43
+ catch (error) {
44
+ log.error("Error fetching agent status:", error);
45
+ res.status(500).json({ error: error.message });
46
+ }
47
+ };
48
+ this.getAgentMemory = async (req, res) => {
49
+ try {
50
+ const { groupId, agentId } = req.params;
51
+ const memory = await this.taskManager.getAgentMemory(groupId, parseInt(agentId), req.redisClient);
52
+ if (!memory) {
53
+ res.status(404).json({ error: "Memory not found" });
54
+ return;
55
+ }
56
+ res.json(memory);
57
+ }
58
+ catch (error) {
59
+ log.error("Error getting agent memory:", error);
60
+ res.status(500).json({ error: error.message });
61
+ }
62
+ };
63
+ this.taskManager = new TaskManager(wsClients);
64
+ this.initializeRoutes();
65
+ }
66
+ initializeRoutes() {
67
+ this.router.post("/:domainId/start", auth.can("view domain"), this.startTask);
68
+ this.router.post("/:domainId/stop", auth.can("view domain"), this.stopTask);
69
+ this.router.get("/:domainId/:agentId/status", auth.can("view domain"), this.agentStatus);
70
+ this.router.get("/:groupId/:agentId/memory", auth.can("view domain"), this.getAgentMemory);
71
+ }
72
+ }
@@ -272,6 +272,10 @@ export class PolicySynthAgentsController {
272
272
  const action = req.body.action;
273
273
  try {
274
274
  const message = await this.agentQueueManager.controlAgent(agentId, action);
275
+ if (action === "start") {
276
+ await this.agentQueueManager.clearAgentStatusMessages(agentId);
277
+ log.debug(`Cleared status messages for agent ${agentId}`);
278
+ }
275
279
  res.json({ message });
276
280
  }
277
281
  catch (error) {
@@ -66,6 +66,7 @@ export class NewAiModelSetup {
66
66
  currency: "USD",
67
67
  },
68
68
  maxTokensOut: 8000,
69
+ maxContextTokens: 200000,
69
70
  defaultTemperature: 0.7,
70
71
  model: "claude-3-5-sonnet-20240620",
71
72
  active: true,
@@ -101,6 +102,7 @@ export class NewAiModelSetup {
101
102
  currency: "USD",
102
103
  },
103
104
  maxTokensOut: 8000,
105
+ maxContextTokens: 200000,
104
106
  defaultTemperature: 0.7,
105
107
  model: "claude-3-7-sonnet-20250219",
106
108
  active: true,
@@ -142,6 +144,7 @@ export class NewAiModelSetup {
142
144
  currency: "USD",
143
145
  },
144
146
  maxTokensOut: 16384,
147
+ maxContextTokens: 128000,
145
148
  defaultTemperature: 0.7,
146
149
  model: "gpt-4o",
147
150
  active: true,
@@ -176,6 +179,7 @@ export class NewAiModelSetup {
176
179
  currency: "USD",
177
180
  },
178
181
  maxTokensOut: 16384,
182
+ maxContextTokens: 128000,
179
183
  defaultTemperature: 0.0,
180
184
  model: "gpt-4o-mini",
181
185
  active: true,
@@ -210,6 +214,7 @@ export class NewAiModelSetup {
210
214
  currency: "USD",
211
215
  },
212
216
  maxTokensOut: 32000,
217
+ maxContextTokens: 128000,
213
218
  defaultTemperature: 0.0,
214
219
  model: "o1-mini",
215
220
  active: true,
@@ -244,6 +249,7 @@ export class NewAiModelSetup {
244
249
  currency: "USD",
245
250
  },
246
251
  maxTokensOut: 32000,
252
+ maxContextTokens: 200000,
247
253
  defaultTemperature: 0.0,
248
254
  model: "o1-preview",
249
255
  active: true,
@@ -278,6 +284,7 @@ export class NewAiModelSetup {
278
284
  currency: "USD",
279
285
  },
280
286
  maxTokensOut: 100000,
287
+ maxContextTokens: 200000,
281
288
  defaultTemperature: 0.0,
282
289
  model: "o1",
283
290
  active: true,
@@ -312,6 +319,7 @@ export class NewAiModelSetup {
312
319
  currency: "USD",
313
320
  },
314
321
  maxTokensOut: 100000,
322
+ maxContextTokens: 200000,
315
323
  defaultTemperature: 0.0,
316
324
  model: "o3-mini",
317
325
  active: true,
@@ -345,6 +353,7 @@ export class NewAiModelSetup {
345
353
  currency: "USD",
346
354
  },
347
355
  maxTokensOut: 100000,
356
+ maxContextTokens: 128000,
348
357
  defaultTemperature: 0.7,
349
358
  model: "gpt-4.5-preview",
350
359
  active: true,
@@ -378,6 +387,7 @@ export class NewAiModelSetup {
378
387
  currency: "USD",
379
388
  },
380
389
  maxTokensOut: 100000,
390
+ maxContextTokens: 200000,
381
391
  defaultTemperature: 0.0,
382
392
  model: "o3",
383
393
  active: true,
@@ -411,6 +421,7 @@ export class NewAiModelSetup {
411
421
  currency: "USD",
412
422
  },
413
423
  maxTokensOut: 100000,
424
+ maxContextTokens: 200000,
414
425
  defaultTemperature: 0.0,
415
426
  model: "o4-mini",
416
427
  active: true,
@@ -444,6 +455,7 @@ export class NewAiModelSetup {
444
455
  costInCachedContextTokensPerMillion: 0.5,
445
456
  },
446
457
  maxTokensOut: 32768,
458
+ maxContextTokens: 1000000,
447
459
  defaultTemperature: 0.7,
448
460
  model: "gpt-4.1",
449
461
  active: true,
@@ -484,6 +496,7 @@ export class NewAiModelSetup {
484
496
  currency: "USD",
485
497
  },
486
498
  maxTokensOut: 8192,
499
+ maxContextTokens: 1000000,
487
500
  defaultTemperature: 0.0,
488
501
  model: "gemini-1.5-pro-002",
489
502
  active: true,
@@ -518,6 +531,7 @@ export class NewAiModelSetup {
518
531
  currency: "USD",
519
532
  },
520
533
  maxTokensOut: 8192,
534
+ maxContextTokens: 1000000,
521
535
  defaultTemperature: 0.0,
522
536
  model: "gemini-1.5-flash-002",
523
537
  active: true,
@@ -552,6 +566,7 @@ export class NewAiModelSetup {
552
566
  currency: "USD",
553
567
  },
554
568
  maxTokensOut: 8192,
569
+ maxContextTokens: 1000000,
555
570
  defaultTemperature: 0.0,
556
571
  model: "gemini-2.0-flash",
557
572
  active: true,
@@ -591,6 +606,7 @@ export class NewAiModelSetup {
591
606
  model: "gemini-2.5-pro",
592
607
  active: true,
593
608
  maxTokensOut: 100000,
609
+ maxContextTokens: 1000000,
594
610
  defaultTemperature: 0.0
595
611
  };
596
612
  if (!gemini25Pro) {
@@ -628,6 +644,7 @@ export class NewAiModelSetup {
628
644
  model: "gemini-2.5-flash-preview-05-20",
629
645
  active: true,
630
646
  maxTokensOut: 100000,
647
+ maxContextTokens: 1000000,
631
648
  defaultTemperature: 0.0
632
649
  };
633
650
  if (!gemini25FlashPreview1) {
@@ -658,7 +675,8 @@ export class NewAiModelSetup {
658
675
  costInCachedContextTokensPerMillion: 0.09,
659
676
  currency: "USD",
660
677
  },
661
- maxTokensOut: 8192,
678
+ maxTokensOut: 32000,
679
+ maxContextTokens: 1000000,
662
680
  defaultTemperature: 0.0,
663
681
  model: "gemini-2.5-flash-preview-05-20",
664
682
  active: true,
@@ -0,0 +1,13 @@
1
+ import WebSocket from "ws";
2
+ import { User as UserClass } from "@policysynth/agents/dbModels/index.js";
3
+ export declare class TaskManager {
4
+ private queueManager;
5
+ private agentManager;
6
+ constructor(wsClients: Map<string, WebSocket>);
7
+ private cloneCommunityTemplate;
8
+ private cloneAgentAssets;
9
+ startTask(communityIdToCloneFrom: number, domainId: number, currentUser: UserClass): Promise<number>;
10
+ stopTask(agentId: number, agentRunId: number, wsClientId: string): Promise<boolean>;
11
+ agentStatus(agentId: number): Promise<PsAgentStatus | null>;
12
+ getAgentMemory(groupId: string, agentId: number, redisClient: any): Promise<any>;
13
+ }
@@ -0,0 +1,155 @@
1
+ import { NotificationAgentQueueManager } from "../managers/notificationAgentQueueManager.js";
2
+ import { AgentManager } from "@policysynth/agents/operations/agentManager.js";
3
+ import models from "../../models/index.cjs";
4
+ import { copyCommunity } from "../../utils/copy_utils.cjs";
5
+ import { PsAgent, PsAgentConnector, PsAiModel, } from "@policysynth/agents/dbModels/index.js";
6
+ export class TaskManager {
7
+ constructor(wsClients) {
8
+ this.queueManager = new NotificationAgentQueueManager(wsClients);
9
+ this.agentManager = new AgentManager();
10
+ }
11
+ async cloneCommunityTemplate(communityTemplateId, toDomainId) {
12
+ return new Promise((resolve, reject) => {
13
+ copyCommunity(communityTemplateId, toDomainId, {
14
+ copyGroups: true,
15
+ copyPosts: false,
16
+ copyPoints: false,
17
+ skipUsers: true,
18
+ recountGroupPosts: true,
19
+ skipEndorsementQualitiesAndRatings: true,
20
+ resetEndorsementCounters: true,
21
+ skipActivities: true,
22
+ }, null, (error, newCommunity) => {
23
+ if (error) {
24
+ reject(error);
25
+ }
26
+ else {
27
+ resolve(newCommunity);
28
+ }
29
+ });
30
+ });
31
+ }
32
+ async cloneAgentAssets(originalAgent, clonedAgent, groupId) {
33
+ // Clone AI Models
34
+ const originalAiModels = await originalAgent.getAiModels();
35
+ if (originalAiModels && originalAiModels.length > 0) {
36
+ await clonedAgent.setAiModels(originalAiModels);
37
+ }
38
+ // Clone Input Connectors
39
+ if (originalAgent.InputConnectors && originalAgent.InputConnectors.length > 0) {
40
+ for (const connector of originalAgent.InputConnectors) {
41
+ const connectorConfig = { ...connector.configuration };
42
+ const clonedConnector = await PsAgentConnector.create({
43
+ user_id: clonedAgent.user_id,
44
+ group_id: groupId,
45
+ class_id: connector.class_id,
46
+ configuration: connectorConfig,
47
+ });
48
+ await models.AgentInputConnectors.create({
49
+ agent_id: clonedAgent.id,
50
+ connector_id: clonedConnector.id,
51
+ });
52
+ }
53
+ }
54
+ // Clone Output Connectors
55
+ if (originalAgent.OutputConnectors && originalAgent.OutputConnectors.length > 0) {
56
+ for (const connector of originalAgent.OutputConnectors) {
57
+ const connectorConfig = { ...connector.configuration };
58
+ const clonedConnector = await PsAgentConnector.create({
59
+ user_id: clonedAgent.user_id,
60
+ group_id: groupId,
61
+ class_id: connector.class_id,
62
+ configuration: connectorConfig,
63
+ });
64
+ await models.AgentOutputConnectors.create({
65
+ agent_id: clonedAgent.id,
66
+ connector_id: clonedConnector.id,
67
+ });
68
+ }
69
+ }
70
+ }
71
+ async startTask(communityIdToCloneFrom, domainId, currentUser) {
72
+ const newCommunity = await this.cloneCommunityTemplate(communityIdToCloneFrom, domainId);
73
+ const groups = await models.Group.findAll({
74
+ where: { community_id: newCommunity.id },
75
+ include: [
76
+ {
77
+ model: models.User,
78
+ as: "GroupAdmins",
79
+ attributes: ["id"],
80
+ required: false,
81
+ },
82
+ ],
83
+ });
84
+ const workflowGroup = groups.find((g) => g.configuration?.agents?.topLevelAgentId);
85
+ if (!workflowGroup) {
86
+ throw new Error("Workflow group not found");
87
+ }
88
+ const topLevelAgentId = workflowGroup.configuration.agents.topLevelAgentId;
89
+ const originalTopLevelAgent = await PsAgent.findByPk(topLevelAgentId, {
90
+ include: [
91
+ {
92
+ model: PsAgent,
93
+ as: "SubAgents",
94
+ include: [
95
+ { model: PsAiModel, as: "AiModels", required: false },
96
+ { model: PsAgentConnector, as: "InputConnectors", required: false },
97
+ { model: PsAgentConnector, as: "OutputConnectors", required: false },
98
+ ],
99
+ },
100
+ ],
101
+ });
102
+ if (!originalTopLevelAgent) {
103
+ throw new Error("Original top level agent not found");
104
+ }
105
+ const clonedTopLevelAgent = await PsAgent.create({
106
+ user_id: currentUser.id,
107
+ class_id: originalTopLevelAgent.class_id,
108
+ configuration: { ...originalTopLevelAgent.configuration },
109
+ group_id: workflowGroup.id,
110
+ parent_agent_id: undefined,
111
+ });
112
+ const clonedSubAgents = [];
113
+ if (originalTopLevelAgent.SubAgents && originalTopLevelAgent.SubAgents.length > 0) {
114
+ for (const subAgent of originalTopLevelAgent.SubAgents) {
115
+ let clonedSub = await PsAgent.create({
116
+ user_id: currentUser.id,
117
+ class_id: subAgent.class_id,
118
+ configuration: { ...subAgent.configuration },
119
+ group_id: workflowGroup.id,
120
+ parent_agent_id: clonedTopLevelAgent.id,
121
+ });
122
+ await this.cloneAgentAssets(subAgent, clonedSub, workflowGroup.id);
123
+ clonedSubAgents.push(clonedSub);
124
+ }
125
+ }
126
+ workflowGroup.configuration.agents.topLevelAgentId = clonedTopLevelAgent.id;
127
+ workflowGroup.changed("configuration", true);
128
+ await workflowGroup.save();
129
+ const userInstance = await models.User.findByPk(currentUser.id);
130
+ if (userInstance) {
131
+ await newCommunity.addCommunityUsers(userInstance);
132
+ await workflowGroup.addGroupAdmins(userInstance);
133
+ await workflowGroup.addGroupUsers(userInstance);
134
+ }
135
+ if (clonedSubAgents.length === 0) {
136
+ throw new Error("No sub agents found to start");
137
+ }
138
+ const firstSubAgentId = clonedSubAgents[0].id;
139
+ await this.queueManager.startAgentProcessing(firstSubAgentId);
140
+ return firstSubAgentId;
141
+ }
142
+ async stopTask(agentId, agentRunId, wsClientId) {
143
+ return this.queueManager.stopAgentProcessing(agentId, wsClientId, agentRunId);
144
+ }
145
+ async agentStatus(agentId) {
146
+ return this.queueManager.getAgentStatus(agentId);
147
+ }
148
+ async getAgentMemory(groupId, agentId, redisClient) {
149
+ const key = await this.agentManager.getSubAgentMemoryKey(groupId, agentId);
150
+ if (!key)
151
+ return null;
152
+ const memoryContents = await redisClient.get(key);
153
+ return memoryContents ? JSON.parse(memoryContents) : null;
154
+ }
155
+ }
package/app.js CHANGED
@@ -578,6 +578,9 @@ export class YourPrioritiesApi {
578
578
  const { AssistantController } = await import("./agents/controllers/assistantsController.js");
579
579
  const assistantController = new AssistantController(this.wsClients);
580
580
  this.app.use(assistantController.path, assistantController.router);
581
+ const { AgentTaskController } = await import("./agents/controllers/agentTaskController.js");
582
+ const agentTaskController = new AgentTaskController(this.wsClients);
583
+ this.app.use(agentTaskController.path, agentTaskController.router);
581
584
  // Setup those here so they wont override the ES controllers
582
585
  this.setupErrorHandler();
583
586
  }
@@ -2374,7 +2374,7 @@ router.get('/auth/oidc/callback', function (req, res) {
2374
2374
  });
2375
2375
  });
2376
2376
  router.get('/auth/audkenni/callback', async function (req, res) {
2377
- await new Promise(resolve => setTimeout(resolve, 100));
2377
+ await new Promise(resolve => setTimeout(resolve, 200));
2378
2378
  req.sso.authenticate('oidc-strategy-' + req.ypDomain.id, {}, req, res, function (error, user) {
2379
2379
  if (error) {
2380
2380
  log.error("Error from Audkenni login", { err: error });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yrpri/api",
3
- "version": "9.0.142",
3
+ "version": "9.0.144",
4
4
  "license": "MIT",
5
5
  "author": "Robert Bjarnason & Citizens Foundation",
6
6
  "repository": {
@@ -25,7 +25,7 @@
25
25
  "@google-cloud/vertexai": "^1.10.0",
26
26
  "@google-cloud/vision": "^5.1.0",
27
27
  "@node-saml/passport-saml": "^5.0.1",
28
- "@policysynth/agents": "^1.3.111",
28
+ "@policysynth/agents": "^1.3.115",
29
29
  "async": "^3.2.6",
30
30
  "authorized": "^1.0.0",
31
31
  "aws-sdk": "^2.1692.0",