@yrpri/api 9.0.99 → 9.0.100

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 (27) hide show
  1. package/agents/assistants/baseAssistant.js +24 -9
  2. package/agents/assistants/modes/agentDirectConnection.js +2 -17
  3. package/agents/assistants/modes/agentSelectionMode.js +5 -8
  4. package/agents/assistants/modes/tools/agentConnectionTools.js +326 -0
  5. package/agents/assistants/modes/tools/agentTools.js +3 -1
  6. package/agents/assistants/modes/tools/loginTools.js +1 -1
  7. package/agents/assistants/modes/tools/models/subscriptions.js +23 -4
  8. package/agents/assistants/modes/tools/navigationTools.js +95 -21
  9. package/agents/assistants/modes/tools/subscriptionTools.js +1 -4
  10. package/agents/assistants/modes/tools/workflowConversationTools.js +326 -0
  11. package/agents/assistants/modes/tools/workflowConverstationTools.js +112 -0
  12. package/agents/assistants/modes/tools/workflowTools.js +112 -0
  13. package/agents/assistants/voiceAssistant.js +3 -3
  14. package/agents/controllers/assistantsController.js +60 -2
  15. package/agents/managers/newAiModelSetup.js +63 -0
  16. package/agents/managers/notificationAgentQueueManager.js +6 -1
  17. package/agents/managers/workflowConversationManager.js +79 -0
  18. package/agents/managers/workflowManager.js +76 -0
  19. package/agents/models/agentProduct.js +37 -24
  20. package/agents/models/agentProductRun.js +9 -0
  21. package/agents/models/testData/setupEvolyAgentProductConfig.js +41 -40
  22. package/agents/models/workflow.js +53 -0
  23. package/agents/models/workflowConversation.js +53 -0
  24. package/agents/models/workflowConverstation.js +53 -0
  25. package/controllers/users.cjs +1 -0
  26. package/migrations/zzzzzzz_create_trees.cjs +81 -0
  27. package/package.json +1 -1
@@ -29,7 +29,7 @@ If interacting in a non-English language, start by using the standard accent or
29
29
  You should always call a function/tool if you can to help the user with their request.
30
30
  Never try to start workflows without using functions/tools, using some tools will unlock other function/tools that might help the user with their request.
31
31
  Functions/tools will become available to you as the user progresses through the workflow.
32
- Make sure that the user logged in and is subscribed to the agent before you start a workflow.
32
+ Make sure that the user logged in before connecting him to an agent.
33
33
  Never list out the available agents using text or markdown, the user already sees the list of agents available for subscription in the UI.
34
34
  You will not be able to start the workflow for the user except using tools/functions at each step.
35
35
  Never engage in longish back and fourth conversations with the user if a workflow has not started, lead the user towards using the tools available as much as possible, politely.
@@ -37,10 +37,10 @@ Never engage in off topic conversations, always politely steer the conversation
37
37
  </coreImportantSystemInstructions>
38
38
 
39
39
  <typicalWorkflowStepsForStartingAnAgentWorkflow>
40
- 1) The user chooses an agent to subscribe to using the direct connect to the agent the user chooses. It's only possible to subscribe to the agent after the user has connected directly to the agent.
41
- 2) The agent offers to show the user a workflow overview, with a tool and then informs the user about the subscription process.
42
- 3) The user logs in or creates an account, if not logged in.
43
- 4) The user verbally confirms a subscription to the agent using a function/tool.
40
+ 1) The agent presents the user with a list of agents available for connection.
41
+ 2) The user logs in or creates an account, if the user is not logged in already.
42
+ 3) The user chooses an agent to connect to using the direct connect to the agent the user chooses.
43
+ 4) The agent offers to show the user a workflow overview, with a tool.
44
44
  5) The user fills out the configuration UI widget.
45
45
  6) The user submits from the configuration UI widget.
46
46
  7) The user starts the workflow run.
@@ -57,7 +57,8 @@ Never engage in off topic conversations, always politely steer the conversation
57
57
  });
58
58
  this.eventEmitter = new EventEmitter();
59
59
  this.setupClientSystemMessageListener();
60
- this.clientSystemMessageListener = this.handleClientSystemMessage.bind(this);
60
+ this.clientSystemMessageListener =
61
+ this.handleClientSystemMessage.bind(this);
61
62
  this.on("update-ai-model-session", this.updateAiModelSession.bind(this));
62
63
  }
63
64
  destroy() {
@@ -108,6 +109,9 @@ Never engage in off topic conversations, always politely steer the conversation
108
109
  });
109
110
  return subscriptionPlan?.AgentProduct;
110
111
  }
112
+ else {
113
+ console.error("--------------------> No subscription plan found");
114
+ }
111
115
  return undefined;
112
116
  }
113
117
  async getCurrentSubscriptionPlan() {
@@ -206,7 +210,8 @@ Never engage in off topic conversations, always politely steer the conversation
206
210
  throw new Error("No agent run found");
207
211
  }
208
212
  console.log(`agent_run_changed emitting`);
209
- this.emit("update-ai-model-session", `The agent run status has been updated to ${agentRun.status} ${JSON.stringify(agentRun.workflow, null, 2)} offer the user assistance with this next step in the workflow`);
213
+ const currentWorkflowStep = agentRun.workflow?.steps[agentRun.workflow?.currentStepIndex];
214
+ this.emit("update-ai-model-session", `The agent run status has been updated to ${agentRun.status} ${JSON.stringify({ workflow: agentRun.workflow, currentWorkflowStep }, null, 2)} offer the user assistance with this next step in the workflow`);
210
215
  }
211
216
  catch (error) {
212
217
  console.error(`Error finding agent run: ${error}`);
@@ -482,6 +487,16 @@ Never engage in off topic conversations, always politely steer the conversation
482
487
  // this.availableTools.get("switch_mode")!,
483
488
  ];
484
489
  }
490
+ get isLoggedIn() {
491
+ return Boolean(this.memory?.currentUser);
492
+ }
493
+ renderLoginStatus() {
494
+ return `
495
+ <loginStatus>
496
+ ${this.isLoggedIn ? "The user is logged in." : "The user is not logged in."}
497
+ </loginStatus>
498
+ `;
499
+ }
485
500
  /**
486
501
  * Get current mode's system prompt
487
502
  */
@@ -489,9 +504,9 @@ Never engage in off topic conversations, always politely steer the conversation
489
504
  const currentMode = this.modes.get(this.memory.currentMode);
490
505
  if (!currentMode) {
491
506
  console.error(`No current mode found: ${this.memory.currentMode}`);
492
- return this.defaultSystemPrompt;
507
+ return `${this.defaultSystemPrompt}\n\n${this.renderLoginStatus()}`;
493
508
  }
494
- return `${this.defaultSystemPrompt}\n\n<furtherAgentInstructions>\n${currentMode.systemPrompt}\n</furtherAgentInstructions>`;
509
+ return `${this.defaultSystemPrompt}\n\n${this.renderLoginStatus()}\n\n<furtherAgentInstructions>\n${currentMode.systemPrompt}\n</furtherAgentInstructions>`;
495
510
  }
496
511
  sendAvatarUrlChange(url, avatarName) {
497
512
  this.wsClientSocket.send(JSON.stringify({
@@ -24,10 +24,8 @@ export class DirectConversationMode extends BaseAssistantMode {
24
24
  // User logged in
25
25
  console.log("Mode: agent_direct_connection_mode, User logged in");
26
26
  tools.push(this.loginTools.logout);
27
+ tools.push(this.agentTools.showAgentWorkflowOverviewWidget);
27
28
  if (this.assistant.isSubscribedToCurrentAgentProduct) {
28
- // User is subscribed to the current agent
29
- console.log("Mode: agent_direct_connection_mode, User is subscribed to the current agent");
30
- tools.push(this.subscriptionTools.unsubscribeFromCurrentAgentSubscription);
31
29
  if (this.assistant.hasConfiguredcurrentAgentProduct) {
32
30
  // User has configured the current agent
33
31
  console.log("Mode: agent_direct_connection_mode, User has configured the current agent");
@@ -61,20 +59,7 @@ export class DirectConversationMode extends BaseAssistantMode {
61
59
  }
62
60
  else {
63
61
  // User is not subscribed to the current agent
64
- console.log("Mode: agent_direct_connection_mode, User is not subscribed to the current agent");
65
- tools.push(this.subscriptionTools.subscribeToCurrentAgentPlan);
66
- tools.push(this.agentTools.showAgentWorkflowOverviewWidget);
67
- }
68
- }
69
- else {
70
- // User not logged in
71
- console.log("Mode: agent_direct_connection_mode, User not logged in");
72
- tools.push(this.loginTools.showLogin("Show login widget to the user if wants to subscribe to an agent or start an agent workflow. Always show the login widget if the user asks to be logged in."));
73
- tools.push(this.agentTools.showAgentWorkflowOverviewWidget);
74
- if (this.assistant.haveShownLoginWidget) {
75
- console.log("Mode: agent_direct_connection_mode, User has shown the login widget");
76
- tools.push(this.loginTools.clickGoogleLoginButton);
77
- tools.push(this.loginTools.clickMainLoginButton);
62
+ console.error("Mode: agent_direct_connection_mode, User is not subscribed to the current agent should not happen");
78
63
  }
79
64
  }
80
65
  return tools;
@@ -1,30 +1,27 @@
1
1
  import { BaseAssistantMode } from "./baseAssistantMode.js";
2
- import { SubscriptionTools } from "./tools/subscriptionTools.js";
3
2
  import { NavigationTools } from "./tools/navigationTools.js";
4
3
  import { LoginAssistantTools } from "./tools/loginTools.js";
5
4
  export class AgentSelectionMode extends BaseAssistantMode {
6
5
  constructor(assistant) {
7
6
  super(assistant);
8
- this.subscriptionTools = new SubscriptionTools(this.assistant);
9
7
  this.navigationTools = new NavigationTools(this.assistant);
10
8
  this.loginTools = new LoginAssistantTools(this.assistant);
11
9
  }
12
10
  async getCurrentModeSystemPrompt() {
13
- let systemPrompt = `You are the main AI agent assistant. Help users select AI agents to subscribe to or connect to. Use your tools when needed.`;
11
+ let systemPrompt = `You are the main AI agent assistant. Help users select AI agent workflows to connect to. Use your tools when needed.`;
14
12
  systemPrompt += await this.renderCommon();
15
13
  return systemPrompt;
16
14
  }
17
15
  async getCurrentModeTools() {
18
16
  const tools = [
19
- this.subscriptionTools.listAllAgentsAvailableForSubscription,
20
- this.navigationTools.connectDirectlyToAgent,
17
+ this.navigationTools.listAllAgentsAvailableForConnection,
21
18
  ];
22
19
  if (this.assistant.isLoggedIn) {
20
+ tools.push(this.navigationTools.connectDirectlyToAgent);
23
21
  tools.push(this.loginTools.logout);
24
- tools.push(this.subscriptionTools.listMyAgentSubscriptions);
25
22
  }
26
23
  else {
27
- tools.push(this.loginTools.showLogin("Show login widget to the user if they ask to be logged in or if they ask specfically to list all of their subscribed agents. You do not need to log in to connect to an agent."));
24
+ tools.push(this.loginTools.showLogin("Show login widget to the user when needed. You do need to log in to connect to an agent. When you have logged in the connect directly to agent tool will be available."));
28
25
  if (this.assistant.haveShownLoginWidget) {
29
26
  tools.push(this.loginTools.clickMainLoginButton);
30
27
  tools.push(this.loginTools.clickGoogleLoginButton);
@@ -38,7 +35,7 @@ export class AgentSelectionMode extends BaseAssistantMode {
38
35
  const tools = await this.getCurrentModeTools();
39
36
  return {
40
37
  name: "agent_selection_mode",
41
- description: "List available agents the user is subscribed to or available for purchase then connect the user to the agent selected by the user",
38
+ description: "List available agents the user can connect to then connect the user to the agent selected by the user",
42
39
  systemPrompt: systemPrompt,
43
40
  tools: tools,
44
41
  allowedTransitions: ["agent_direct_connection_mode"],
@@ -0,0 +1,326 @@
1
+ // commonTools.ts
2
+ import { SubscriptionModels } from "./models/subscriptions.js";
3
+ import { BaseAssistantTools } from "./baseTools.js";
4
+ export class SubscriptionTools extends BaseAssistantTools {
5
+ constructor(assistant) {
6
+ super(assistant);
7
+ this.subscriptionModels = new SubscriptionModels(assistant);
8
+ }
9
+ get listMyAgentSubscriptions() {
10
+ return {
11
+ name: "list_my_agent_subscriptions",
12
+ description: "List all agent subscriptions for the current user.",
13
+ type: "function",
14
+ parameters: {
15
+ type: "object",
16
+ properties: {},
17
+ },
18
+ handler: this.listMyAgentSubscriptionsHandler.bind(this),
19
+ };
20
+ }
21
+ async listMyAgentSubscriptionsHandler(params) {
22
+ params = this.assistant.getCleanedParams(params);
23
+ console.log(`handler: list_my_agent_subscriptions: ${JSON.stringify(params, null, 2)}`);
24
+ try {
25
+ const status = await this.subscriptionModels.loadUserAgentSubscriptions();
26
+ if (this.assistant.DEBUG) {
27
+ console.log(`list_my_agent_subscriptions: ${JSON.stringify(status, null, 2)}`);
28
+ }
29
+ let agentChips = "";
30
+ for (const subscription of status.availableSubscriptions) {
31
+ agentChips += `<div class="agent-chips"><yp-agent-chip-for-purchase
32
+ isSubscribed="${true}"
33
+ type="${subscription.Plan?.configuration.type}"
34
+ agentProductId="${subscription.Plan?.AgentProduct?.id}"
35
+ subscriptionPlanId="${subscription.Plan?.id}"
36
+ agentName="${subscription.Plan?.AgentProduct?.name}"
37
+ agentDescription="${subscription.Plan?.AgentProduct?.description}"
38
+ agentImageUrl="${subscription.Plan?.AgentProduct?.configuration.avatar?.imageUrl}"
39
+ price="${subscription.Plan?.configuration.amount}"
40
+ currency="${subscription.Plan?.configuration.currency}"
41
+ maxRunsPerCycle="${subscription.Plan?.configuration.max_runs_per_cycle}"
42
+ ></yp-agent-chip-for-purchase></div>`;
43
+ }
44
+ let html;
45
+ if (status.availableSubscriptions.length > 0) {
46
+ html = `<div class="agent-chips">${agentChips}</div>`;
47
+ }
48
+ else {
49
+ this.assistant.triggerResponseIfNeeded("The user is not subscribed to any agents, offer to show available agents for purchase");
50
+ }
51
+ return {
52
+ success: true,
53
+ data: status,
54
+ html,
55
+ metadata: {
56
+ timestamp: new Date().toISOString(),
57
+ },
58
+ };
59
+ }
60
+ catch (error) {
61
+ const errorMessage = error instanceof Error ? error.message : "Failed to load agent status";
62
+ console.error(`Failed to load agent status: ${errorMessage}`);
63
+ return {
64
+ success: false,
65
+ data: errorMessage,
66
+ error: errorMessage,
67
+ };
68
+ }
69
+ }
70
+ get listAllAgentsAvailableForSubscription() {
71
+ return {
72
+ name: "list_all_agents_available_for_subscription",
73
+ description: "List all agent subscriptions available for purchase",
74
+ type: "function",
75
+ parameters: {
76
+ type: "object",
77
+ properties: {},
78
+ },
79
+ handler: this.listAllAgentsAvailableForSubscriptionHandler.bind(this),
80
+ };
81
+ }
82
+ async listAllAgentsAvailableForSubscriptionHandler(params) {
83
+ params = this.assistant.getCleanedParams(params);
84
+ console.log(`handler: list_all_agents_available_for_purchase: ${JSON.stringify(params, null, 2)}`);
85
+ try {
86
+ const status = await this.subscriptionModels.loadAgentSubscriptionPlans();
87
+ if (this.assistant.DEBUG) {
88
+ console.log(`list_all_agents_available_for_purchase: ${JSON.stringify(status, null, 2)}`);
89
+ }
90
+ let agentChips = "";
91
+ function planTypePriority(type) {
92
+ switch (type) {
93
+ case "coming_soon":
94
+ return 0;
95
+ case "paid":
96
+ return 1;
97
+ case "free_trial":
98
+ return 2;
99
+ default:
100
+ return 999;
101
+ }
102
+ }
103
+ // 2) Custom sort function
104
+ const sortedPlans = [...status.availablePlans].sort((a, b) => {
105
+ // Compare by type priority first
106
+ const typeComparison = planTypePriority(a.type) - planTypePriority(b.type);
107
+ if (typeComparison !== 0) {
108
+ // If types differ, that decides the order
109
+ return typeComparison;
110
+ }
111
+ // If both are the same type and it's "paid", sort by price descending
112
+ if (a.type === "paid" && b.type === "paid") {
113
+ return b.price - a.price;
114
+ }
115
+ // Otherwise keep them in the same order if they're not "paid"
116
+ return 0;
117
+ });
118
+ for (const agent of sortedPlans) {
119
+ agentChips += `<yp-agent-chip-for-purchase
120
+ subscriptionPlanId="${agent.subscriptionPlanId}"
121
+ type="${agent.type}"
122
+ agentName="${agent.name}"
123
+ agentDescription="${agent.description}"
124
+ agentImageUrl="${agent.imageUrl}"
125
+ price="${agent.price}"
126
+ currency="${agent.currency}"
127
+ maxRunsPerCycle="${agent.maxRunsPerCycle}"
128
+ ></yp-agent-chip-for-purchase>`;
129
+ }
130
+ const html = `<div class="agent-chips">${agentChips}</div>`;
131
+ return {
132
+ success: true,
133
+ data: {
134
+ messageToAssistant: "You have shown the user the available agents for purchase with a UI widget, now the user needs to choose which one to connect to then subscribe to",
135
+ status,
136
+ },
137
+ html,
138
+ metadata: {
139
+ timestamp: new Date().toISOString(),
140
+ },
141
+ };
142
+ }
143
+ catch (error) {
144
+ const errorMessage = error instanceof Error ? error.message : "Failed to load agent status";
145
+ console.error(`Failed to load agent status: ${errorMessage}`);
146
+ return {
147
+ success: false,
148
+ data: errorMessage,
149
+ error: errorMessage,
150
+ };
151
+ }
152
+ }
153
+ get subscribeToCurrentAgentPlan() {
154
+ return {
155
+ name: "subscribe_to_current_agent_plan",
156
+ description: "Subscribe to the current agent plan. User must confirm subscription with the agent name before proceeding. The user needs to subscribe to the agent before it can be used so make sure to offer it to the user.",
157
+ type: "function",
158
+ parameters: {
159
+ type: "object",
160
+ properties: {
161
+ useHasVerballyConfirmedSubscribeWithTheAgentName: {
162
+ type: "boolean",
163
+ },
164
+ },
165
+ required: [
166
+ "useHasVerballyConfirmedSubscribeWithTheAgentName",
167
+ ],
168
+ },
169
+ handler: this.subscribeToCurrentAgentPlanHandler.bind(this),
170
+ };
171
+ }
172
+ async subscribeToCurrentAgentPlanHandler(params) {
173
+ params = this.assistant.getCleanedParams(params);
174
+ console.log(`handler: subscribe_to_current_agent_plan: ${JSON.stringify(params, null, 2)}`);
175
+ try {
176
+ if (!params.useHasVerballyConfirmedSubscribeWithTheAgentName) {
177
+ return {
178
+ success: false,
179
+ error: "User must confirm subscription with the agent name before proceeding",
180
+ };
181
+ }
182
+ console.log(`-------> ${JSON.stringify(this.assistant.memory.currentAgentStatus, null, 2)}`);
183
+ const subscriptionPlan = await this.assistant.getCurrentSubscriptionPlan();
184
+ if (!subscriptionPlan) {
185
+ throw new Error("No subscription plan found");
186
+ }
187
+ if (!subscriptionPlan) {
188
+ return {
189
+ success: false,
190
+ data: "No current agent selected",
191
+ error: "No current agent selected",
192
+ };
193
+ }
194
+ const result = await this.subscriptionModels.subscribeToAgentPlan(subscriptionPlan.AgentProduct.id, subscriptionPlan.id);
195
+ if (!result.success || !result.subscription || !result.plan) {
196
+ return {
197
+ success: false,
198
+ error: result.error || "Failed to subscribe to agent plan",
199
+ };
200
+ }
201
+ await this.updateCurrentAgentProductPlan(result.plan, result.subscription);
202
+ let html;
203
+ if (result.plan?.AgentProduct) {
204
+ html = `<div class="agent-chips"><yp-agent-chip-for-purchase
205
+ isSubscribed="${true}"
206
+ agentProductId="${result.plan.AgentProduct.id}"
207
+ subscriptionPlanId="${result.plan.id}"
208
+ agentName="${result.plan.AgentProduct.configuration.displayName}"
209
+ agentDescription="${result.plan.AgentProduct.description}"
210
+ agentImageUrl="${result.plan.AgentProduct.configuration.avatar?.imageUrl}"
211
+ price="${result.plan.configuration.amount}"
212
+ currency="${result.plan.configuration.currency}"
213
+ maxRunsPerCycle="${result.plan.configuration.max_runs_per_cycle}"
214
+ ></yp-agent-chip-for-purchase></div>`;
215
+ }
216
+ this.assistant.emit("update-ai-model-session", "Successfully subscribed to agent plan, now offer to show the configuration input tool/widget to configure the agent");
217
+ return {
218
+ success: true,
219
+ html,
220
+ data: {
221
+ message: "Successfully subscribed to agent plan, now offer to show the configuration input tool/widget to configure the agent",
222
+ subscription: result.subscription,
223
+ subscriptionPlan: result.plan,
224
+ },
225
+ };
226
+ }
227
+ catch (error) {
228
+ const errorMessage = error instanceof Error ? error.message : "Failed to subscribe to agent";
229
+ console.error(`Failed to subscribe to agent: ${errorMessage}`);
230
+ return {
231
+ success: false,
232
+ error: errorMessage,
233
+ };
234
+ }
235
+ }
236
+ get unsubscribeFromCurrentAgentSubscription() {
237
+ return {
238
+ name: "unsubscribe_from_current_agent_subscription",
239
+ description: "Unsubscribe from an existing agent subscription the user is subscribed to. User must verbally confirm unsubscription with the agent name before proceeding.",
240
+ type: "function",
241
+ parameters: {
242
+ type: "object",
243
+ properties: {
244
+ useHasVerballyConfirmedUnsubscribeWithTheAgentName: {
245
+ type: "boolean",
246
+ },
247
+ },
248
+ required: [
249
+ "useHasVerballyConfirmedUnsubscribeWithTheAgentName",
250
+ ],
251
+ },
252
+ handler: this.unsubscribeFromCurrentAgentSubscriptionHandler.bind(this),
253
+ };
254
+ }
255
+ async unsubscribeFromCurrentAgentSubscriptionHandler(params) {
256
+ params = this.assistant.getCleanedParams(params);
257
+ console.log(`handler: unsubscribe_from_current_agent_subscription: ${JSON.stringify(params, null, 2)}`);
258
+ try {
259
+ if (!params.useHasVerballyConfirmedUnsubscribeWithTheAgentName) {
260
+ return {
261
+ success: false,
262
+ error: "User must verbally confirm unsubscription with the agent name before proceeding",
263
+ };
264
+ }
265
+ const subscriptionPlan = await this.assistant.getCurrentSubscriptionPlan();
266
+ if (!subscriptionPlan) {
267
+ return {
268
+ success: false,
269
+ data: "No current agent selected",
270
+ error: "No current agent selected",
271
+ };
272
+ }
273
+ const { plan, subscription } = await this.subscriptionModels.loadAgentProductPlanAndSubscription(subscriptionPlan.id);
274
+ if (!subscription) {
275
+ return {
276
+ success: false,
277
+ data: "No subscription found",
278
+ error: "No subscription found",
279
+ };
280
+ }
281
+ if (!plan) {
282
+ return {
283
+ success: false,
284
+ data: "No subscription plan found",
285
+ error: "No subscription plan found",
286
+ };
287
+ }
288
+ const result = await this.subscriptionModels.unsubscribeFromAgentPlan(subscription.id);
289
+ if (!result.success) {
290
+ return {
291
+ success: false,
292
+ error: result.error,
293
+ };
294
+ }
295
+ await this.updateCurrentAgentProductPlan(plan, subscription);
296
+ const html = `<div class="agent-chips"><yp-agent-chip
297
+ isUnsubscribed="${true}"
298
+ agentProductId="${plan.AgentProduct?.id}"
299
+ subscriptionId="${subscription.id}"
300
+ agentName="${plan.AgentProduct?.name}"
301
+ agentDescription="${plan.AgentProduct?.description}"
302
+ agentImageUrl="${plan.AgentProduct?.configuration.avatar?.imageUrl}"
303
+ ></yp-agent-chip></div>`;
304
+ this.assistant.emit("update-ai-model-session", "Successfully unsubscribed from agent subscription");
305
+ return {
306
+ success: true,
307
+ html,
308
+ data: {
309
+ message: "Successfully unsubscribed from agent subscription",
310
+ subscriptionId: result.subscriptionId,
311
+ subscriptionPlan: plan,
312
+ },
313
+ };
314
+ }
315
+ catch (error) {
316
+ const errorMessage = error instanceof Error
317
+ ? error.message
318
+ : "Failed to unsubscribe from agent";
319
+ console.error(`Failed to unsubscribe from agent: ${errorMessage}`);
320
+ return {
321
+ success: false,
322
+ error: errorMessage,
323
+ };
324
+ }
325
+ }
326
+ }
@@ -20,6 +20,7 @@ export class AgentTools extends BaseAssistantTools {
20
20
  async showAgentWorkflowOverviewWidgetHandler(params) {
21
21
  try {
22
22
  const { agent, run } = await this.agentModels.getCurrentAgentAndWorkflow();
23
+ console.log("--------------------> agent", agent);
23
24
  const workflowJson = JSON.stringify(this.getSimpleWorkflow(agent.configuration.workflow));
24
25
  const base64Workflow = btoa(workflowJson);
25
26
  const html = `<yp-agent-workflow-widget
@@ -57,6 +58,7 @@ export class AgentTools extends BaseAssistantTools {
57
58
  ? error.message
58
59
  : "Failed to show workflow widget";
59
60
  console.error(errorMessage);
61
+ console.error("--------------------_> ", error);
60
62
  return {
61
63
  success: false,
62
64
  error: errorMessage,
@@ -332,7 +334,7 @@ export class AgentTools extends BaseAssistantTools {
332
334
  return {
333
335
  name: "show_configuration_widget_if_needed_or_user_asks_to_show_it",
334
336
  description: "Show the configuration widget for the current agent. The user needs to fill out the configuration before running the agent workflow to make sure to offer it to the user. \
335
- The user can not provide you with the confiruation verbally or through chat, the user must provide the configuration through the configuration widget.",
337
+ The user can not provide you with the configuration verbally or through chat, the user must provide the configuration through the configuration widget.",
336
338
  type: "function",
337
339
  parameters: {
338
340
  type: "object",
@@ -105,7 +105,7 @@ export class LoginAssistantTools extends BaseAssistantTools {
105
105
  get logout() {
106
106
  return {
107
107
  name: "logout",
108
- description: "Log out from the system with confirmation if the user asks for it",
108
+ description: "Log out from the system with confirmation if the user asks for it. If this tools is showing it means that the user is already logged in.",
109
109
  type: "function",
110
110
  parameters: {
111
111
  type: "object",
@@ -53,9 +53,9 @@ export class SubscriptionModels {
53
53
  name: plan.AgentProduct?.configuration?.displayName || "No name available",
54
54
  description: plan.AgentProduct?.description || "No description available",
55
55
  imageUrl: plan.configuration?.imageUrl || "",
56
- price: plan.configuration?.amount || 0,
57
- currency: plan.configuration?.currency || "USD",
58
- maxRunsPerCycle: plan.configuration?.max_runs_per_cycle || 0,
56
+ // price: plan.configuration?.amount || 0,
57
+ // currency: plan.configuration?.currency || "USD",
58
+ // maxRunsPerCycle: plan.configuration?.max_runs_per_cycle || 0,
59
59
  })),
60
60
  availableBundle: firstBundle
61
61
  ? {
@@ -256,7 +256,7 @@ export class SubscriptionModels {
256
256
  };
257
257
  }
258
258
  }
259
- async subscribeToAgentPlan(agentProductId, subscriptionPlanId) {
259
+ async subscribeToAgentPlan(agentProductId, subscriptionPlanId, returnCurrentSubscription = false) {
260
260
  try {
261
261
  const plan = await YpSubscriptionPlan.findOne({
262
262
  where: {
@@ -282,6 +282,25 @@ export class SubscriptionModels {
282
282
  error: "User not found",
283
283
  };
284
284
  }
285
+ const existingSubscription = await YpSubscription.findOne({
286
+ where: {
287
+ subscription_plan_id: subscriptionPlanId,
288
+ user_id: userId,
289
+ },
290
+ });
291
+ if (returnCurrentSubscription && existingSubscription) {
292
+ return {
293
+ success: true,
294
+ plan: plan,
295
+ subscription: existingSubscription,
296
+ };
297
+ }
298
+ else if (existingSubscription) {
299
+ return {
300
+ success: false,
301
+ error: "User already subscribed to this plan",
302
+ };
303
+ }
285
304
  console.log(`-------> subscribing to agent plan ${subscriptionPlanId} for user ${userId}`);
286
305
  const subscription = await YpSubscription.create({
287
306
  subscription_plan_id: subscriptionPlanId,