@yrpri/api 9.0.99 → 9.0.101
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.
- package/agents/assistants/baseAssistant.js +24 -9
- package/agents/assistants/modes/agentDirectConnection.js +2 -17
- package/agents/assistants/modes/agentSelectionMode.js +5 -8
- package/agents/assistants/modes/tools/agentConnectionTools.js +326 -0
- package/agents/assistants/modes/tools/agentTools.js +3 -1
- package/agents/assistants/modes/tools/loginTools.js +1 -1
- package/agents/assistants/modes/tools/models/subscriptions.js +23 -4
- package/agents/assistants/modes/tools/navigationTools.js +95 -21
- package/agents/assistants/modes/tools/subscriptionTools.js +1 -4
- package/agents/assistants/modes/tools/workflowConversationTools.js +326 -0
- package/agents/assistants/modes/tools/workflowConverstationTools.js +112 -0
- package/agents/assistants/modes/tools/workflowTools.js +112 -0
- package/agents/assistants/voiceAssistant.js +3 -3
- package/agents/controllers/assistantsController.js +60 -2
- package/agents/managers/newAiModelSetup.js +63 -0
- package/agents/managers/notificationAgentQueueManager.js +6 -1
- package/agents/managers/workflowConversationManager.js +79 -0
- package/agents/managers/workflowManager.js +76 -0
- package/agents/models/agentProduct.js +37 -24
- package/agents/models/agentProductRun.js +9 -0
- package/agents/models/testData/setupEvolyAgentProductConfig.js +41 -40
- package/agents/models/workflow.js +53 -0
- package/agents/models/workflowConversation.js +53 -0
- package/agents/models/workflowConverstation.js +53 -0
- package/controllers/users.cjs +1 -0
- package/migrations/zzzzzzz_create_trees.cjs +81 -0
- 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
|
|
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
|
|
41
|
-
2) The
|
|
42
|
-
3) The user
|
|
43
|
-
4) The
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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,
|