@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
|
@@ -5,7 +5,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
5
5
|
const CompetitorAgentFreeTrialPlan = await YpSubscriptionPlan.findByPk(1);
|
|
6
6
|
if (CompetitorAgentFreeTrialPlan) {
|
|
7
7
|
await CompetitorAgentFreeTrialPlan.update({
|
|
8
|
-
name: "Competitor Agent
|
|
8
|
+
name: "Competitor Agent",
|
|
9
9
|
description: "Competitive reports give detailed insights into competitors' strategies, product changes, and market moves - all synthesized into actionable market intelligence for your business.",
|
|
10
10
|
});
|
|
11
11
|
}
|
|
@@ -33,27 +33,27 @@ async function setupAgentProductsConfiguration() {
|
|
|
33
33
|
const CompetitorAgentFreeTrial = await YpAgentProduct.findByPk(1);
|
|
34
34
|
if (CompetitorAgentFreeTrial) {
|
|
35
35
|
const configuration = {
|
|
36
|
+
...CompetitorAgentFreeTrial.configuration,
|
|
36
37
|
avatar: {
|
|
37
|
-
systemPrompt: `You are the Competitor Agent. You are an expert in analyzing competitor strategies and market positions. You
|
|
38
|
+
systemPrompt: `You are the Competitor Agent. You are an expert in analyzing competitor strategies and market positions. You will perform the following steps:
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
1. Wide Search: You need to search for competitor strategies and market positions.
|
|
41
|
-
2. People Review: You need to prioritize the wide search results.
|
|
42
|
-
3. Detailed Search: You need to search for competitor strategies and market positions in more detail.
|
|
43
|
-
4. Detailed Search People Review: You need to prioritize the detailed search results.
|
|
44
|
-
5. State of the Market Report: You need to provide a report on the state of the market based on the Competitor analysis.
|
|
40
|
+
1. Wide search for competitors: A wide search for competitors based on the provided business description.
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
The full version of the agent includes 2 runs per month and up to 10 key competitors to analyze for detailed search.
|
|
42
|
+
2. Vet and vote top 10 competitors: The user's team reviews and votes on competitors from the wide search results.
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
3. Detailed search on key competitors: Perform detailed searches on the selected key competitors, gathering multi-dimensional data.
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
4. Add team insights about key competitors: Allow the user's team to add their insights and comments on key competitors.
|
|
47
|
+
|
|
48
|
+
5. Competitor analysis report: Generate a comprehensive report consolidating all data and insights, including actionable recommendations.
|
|
49
|
+
|
|
50
|
+
The output is a state-of-the-market competitor analysis report in DOCX formats.
|
|
51
|
+
|
|
52
|
+
Please guide the user through this process clearly and educate them about competitor analysis, your specialty.`,
|
|
53
53
|
imageUrl: "https://assets.evoly.ai/dl/754a1e727d768b1107826c1deb67b6ac--retina-1.png",
|
|
54
54
|
voiceName: "shimmer",
|
|
55
55
|
},
|
|
56
|
-
displayName: "Competitor Agent
|
|
56
|
+
displayName: "Competitor Agent",
|
|
57
57
|
displayDescription: "Plan includes <span class='textBold'>1 run per month</span> and details for <span class='text-bold'>3 key competitors</span>.",
|
|
58
58
|
};
|
|
59
59
|
await CompetitorAgentFreeTrial.update({
|
|
@@ -64,34 +64,30 @@ async function setupAgentProductsConfiguration() {
|
|
|
64
64
|
}
|
|
65
65
|
const CompetitorAgent = await YpAgentProduct.findByPk(2);
|
|
66
66
|
if (CompetitorAgent) {
|
|
67
|
-
|
|
68
|
-
CompetitorAgent.configuration
|
|
69
|
-
|
|
67
|
+
CompetitorAgent.configuration.avatar = {
|
|
68
|
+
...CompetitorAgent.configuration,
|
|
69
|
+
systemPrompt: `You are the Competitor Agent. You are an expert in analyzing competitor strategies and market positions. You will perform the following steps:
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
1. Wide search for competitors: A wide search for competitors based on the provided business description.
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
2. Vet and vote top 10 competitors: The user's team reviews and votes on competitors from the wide search results.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
1. Wide Search: You need to search for competitor strategies and market positions.
|
|
77
|
-
2. People Review: You need to prioritize the wide search results.
|
|
78
|
-
3. Detailed Search: You need to search for competitor strategies and market positions in more detail.
|
|
79
|
-
4. Detailed Search People Review: You need to prioritize the detailed search results.
|
|
80
|
-
5. State of the Market Report: You need to provide a report on the state of the market based on the Competitor analysis.
|
|
75
|
+
3. Detailed search on key competitors: Perform detailed searches on the selected key competitors, gathering multi-dimensional data.
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
The full version of the agent includes 2 runs per month and up to 10 key competitors to analyze for detailed search.
|
|
77
|
+
4. Add team insights about key competitors: Allow the user's team to add their insights and comments on key competitors.
|
|
84
78
|
|
|
85
|
-
|
|
79
|
+
5. Competitor analysis report: Generate a comprehensive report consolidating all data and insights, including actionable recommendations.
|
|
86
80
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
CompetitorAgent.configuration.
|
|
81
|
+
The output is a state-of-the-market competitor analysis report in DOCX formats.
|
|
82
|
+
|
|
83
|
+
Please guide the user through this process clearly and educate them about competitor analysis, your specialty.
|
|
84
|
+
`,
|
|
85
|
+
imageUrl: "https://assets.evoly.ai/dl/754a1e727d768b1107826c1deb67b6ac--retina-1.png",
|
|
86
|
+
voiceName: "shimmer",
|
|
87
|
+
};
|
|
88
|
+
CompetitorAgent.configuration.displayName = "Competitor Agent";
|
|
89
|
+
CompetitorAgent.configuration.displayDescription =
|
|
90
|
+
"Plan includes <span class='textBold'>2 runs per month</span> and details for <span class='text-bold'>12 key competitors</span>.";
|
|
95
91
|
CompetitorAgent.changed("configuration", true);
|
|
96
92
|
await CompetitorAgent.save();
|
|
97
93
|
await CompetitorAgent.update({
|
|
@@ -102,6 +98,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
102
98
|
const leadGenerationAgent = await YpAgentProduct.findByPk(3);
|
|
103
99
|
if (leadGenerationAgent) {
|
|
104
100
|
await leadGenerationAgent.update({
|
|
101
|
+
...leadGenerationAgent.configuration,
|
|
105
102
|
description: "Define your ideal customer, and receive curated lead lists you can sync to your CRM - turning potential prospects into qualified opportunities.",
|
|
106
103
|
configuration: {
|
|
107
104
|
avatar: {
|
|
@@ -123,7 +120,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
123
120
|
imageUrl: "https://assets.evoly.ai/dl/f86bf2c221801b4c56d71b098c36ef54--retina-1.png",
|
|
124
121
|
voiceName: "ash",
|
|
125
122
|
},
|
|
126
|
-
displayName: "Lead Generation Agent
|
|
123
|
+
displayName: "Lead Generation Agent",
|
|
127
124
|
displayDescription: "Plan includes <span class='textBold'>4 runs per month</span> and details for <span class='text-bold'>100 leads</span>.",
|
|
128
125
|
},
|
|
129
126
|
});
|
|
@@ -131,6 +128,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
131
128
|
const productInnovationAgent = await YpAgentProduct.findByPk(4);
|
|
132
129
|
if (productInnovationAgent) {
|
|
133
130
|
await productInnovationAgent.update({
|
|
131
|
+
...productInnovationAgent.configuration,
|
|
134
132
|
name: "Product Innovation Agent",
|
|
135
133
|
description: "Fresh product ideas come with market context, user needs analysis, and implementation considerations - turning market gaps into new innovations.",
|
|
136
134
|
configuration: {
|
|
@@ -152,7 +150,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
152
150
|
imageUrl: "https://assets.evoly.ai/dl/1d91f5bfb69446f57c678a4a3e873d35--retina-1.png",
|
|
153
151
|
voiceName: "coral",
|
|
154
152
|
},
|
|
155
|
-
displayName: "Product Innovation Agent
|
|
153
|
+
displayName: "Product Innovation Agent",
|
|
156
154
|
displayDescription: "Plan includes <span class='textBold'>4 runs per month</span> and details for <span class='text-bold'>100 innovative ideas</span>.",
|
|
157
155
|
},
|
|
158
156
|
});
|
|
@@ -160,6 +158,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
160
158
|
const marketingOpsAgent = await YpAgentProduct.findByPk(5);
|
|
161
159
|
if (marketingOpsAgent) {
|
|
162
160
|
await marketingOpsAgent.update({
|
|
161
|
+
...marketingOpsAgent.configuration,
|
|
163
162
|
description: "Choose from AI-generated blog posts, refine them to your taste, and watch as they automatically spread across your social channels - keeping your brand consistently visible and engaging.",
|
|
164
163
|
configuration: {
|
|
165
164
|
avatar: {
|
|
@@ -196,7 +195,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
196
195
|
imageUrl: "https://assets.evoly.ai/dl/6f8757bfb637206ddae009597aa4ab6d--retina-1.png",
|
|
197
196
|
voiceName: "alloy",
|
|
198
197
|
},
|
|
199
|
-
displayName: "Marketing Ops Agent
|
|
198
|
+
displayName: "Marketing Ops Agent",
|
|
200
199
|
displayDescription: "Plan includes <span class='textBold'>8 runs per month</span> and details for <span class='text-bold'>100 pieces of content</span>.",
|
|
201
200
|
},
|
|
202
201
|
});
|
|
@@ -204,8 +203,10 @@ async function setupAgentProductsConfiguration() {
|
|
|
204
203
|
const fundingAgent = await YpAgentProduct.findByPk(6);
|
|
205
204
|
if (fundingAgent) {
|
|
206
205
|
await fundingAgent.update({
|
|
206
|
+
...fundingAgent.configuration,
|
|
207
207
|
description: "Potential investors are identified with details about their portfolio, investment focus, and recent activities - turning raw investor data into actionable opportunities.",
|
|
208
208
|
configuration: {
|
|
209
|
+
...fundingAgent.configuration,
|
|
209
210
|
avatar: {
|
|
210
211
|
systemPrompt: `You are the Funding Agent. You are an expert in identifying and analyzing funding opportunities and investment strategies. You are given a business description and you need to identify and analyze funding opportunities and investment strategies. You need to provide a report on the funding opportunities and investment strategies.
|
|
211
212
|
|
|
@@ -223,7 +224,7 @@ async function setupAgentProductsConfiguration() {
|
|
|
223
224
|
imageUrl: "https://assets.evoly.ai/dl/f80b64c1ab385e6f3ec0d3f552f38801--retina-1.png",
|
|
224
225
|
voiceName: "ballad",
|
|
225
226
|
},
|
|
226
|
-
displayName: "Funding Agent
|
|
227
|
+
displayName: "Funding Agent",
|
|
227
228
|
displayDescription: "Plan includes <span class='textBold'>2 runs per month</span> and details for <span class='text-bold'>20 funding opportunities</span>.",
|
|
228
229
|
},
|
|
229
230
|
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Model, DataTypes } from "sequelize";
|
|
2
|
+
import { sequelize } from "@policysynth/agents/dbModels/sequelize.js";
|
|
3
|
+
export class YpWorkflowConversation extends Model {
|
|
4
|
+
static initModel(sequelizeInstance = sequelize) {
|
|
5
|
+
YpWorkflowConversation.init({
|
|
6
|
+
id: {
|
|
7
|
+
type: DataTypes.INTEGER,
|
|
8
|
+
primaryKey: true,
|
|
9
|
+
autoIncrement: true,
|
|
10
|
+
},
|
|
11
|
+
agentProductId: {
|
|
12
|
+
type: DataTypes.INTEGER,
|
|
13
|
+
allowNull: true,
|
|
14
|
+
field: "agent_product_id",
|
|
15
|
+
},
|
|
16
|
+
userId: {
|
|
17
|
+
type: DataTypes.INTEGER,
|
|
18
|
+
allowNull: false,
|
|
19
|
+
field: "user_id",
|
|
20
|
+
},
|
|
21
|
+
configuration: {
|
|
22
|
+
type: DataTypes.JSONB,
|
|
23
|
+
allowNull: false,
|
|
24
|
+
defaultValue: {},
|
|
25
|
+
},
|
|
26
|
+
created_at: {
|
|
27
|
+
type: DataTypes.DATE,
|
|
28
|
+
allowNull: false,
|
|
29
|
+
defaultValue: DataTypes.NOW,
|
|
30
|
+
},
|
|
31
|
+
updated_at: {
|
|
32
|
+
type: DataTypes.DATE,
|
|
33
|
+
allowNull: false,
|
|
34
|
+
defaultValue: DataTypes.NOW,
|
|
35
|
+
},
|
|
36
|
+
}, {
|
|
37
|
+
sequelize: sequelizeInstance,
|
|
38
|
+
tableName: "workflows",
|
|
39
|
+
timestamps: false,
|
|
40
|
+
});
|
|
41
|
+
return YpWorkflowConversation;
|
|
42
|
+
}
|
|
43
|
+
static associate(models) {
|
|
44
|
+
YpWorkflowConversation.belongsTo(models.YpAgentProduct, {
|
|
45
|
+
foreignKey: "agentProductId",
|
|
46
|
+
as: "agentProduct",
|
|
47
|
+
});
|
|
48
|
+
YpWorkflowConversation.hasMany(models.YpAgentProductRun, {
|
|
49
|
+
foreignKey: "workflowId",
|
|
50
|
+
as: "agentProductRuns",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Model, DataTypes } from "sequelize";
|
|
2
|
+
import { sequelize } from "@policysynth/agents/dbModels/sequelize.js";
|
|
3
|
+
export class YpWorkflowConversation extends Model {
|
|
4
|
+
static initModel(sequelizeInstance = sequelize) {
|
|
5
|
+
YpWorkflowConversation.init({
|
|
6
|
+
id: {
|
|
7
|
+
type: DataTypes.INTEGER,
|
|
8
|
+
primaryKey: true,
|
|
9
|
+
autoIncrement: true,
|
|
10
|
+
},
|
|
11
|
+
agentProductId: {
|
|
12
|
+
type: DataTypes.INTEGER,
|
|
13
|
+
allowNull: true,
|
|
14
|
+
field: "agent_product_id",
|
|
15
|
+
},
|
|
16
|
+
userId: {
|
|
17
|
+
type: DataTypes.INTEGER,
|
|
18
|
+
allowNull: false,
|
|
19
|
+
field: "user_id",
|
|
20
|
+
},
|
|
21
|
+
configuration: {
|
|
22
|
+
type: DataTypes.JSONB,
|
|
23
|
+
allowNull: false,
|
|
24
|
+
defaultValue: {},
|
|
25
|
+
},
|
|
26
|
+
created_at: {
|
|
27
|
+
type: DataTypes.DATE,
|
|
28
|
+
allowNull: false,
|
|
29
|
+
defaultValue: DataTypes.NOW,
|
|
30
|
+
},
|
|
31
|
+
updated_at: {
|
|
32
|
+
type: DataTypes.DATE,
|
|
33
|
+
allowNull: false,
|
|
34
|
+
defaultValue: DataTypes.NOW,
|
|
35
|
+
},
|
|
36
|
+
}, {
|
|
37
|
+
sequelize: sequelizeInstance,
|
|
38
|
+
tableName: "workflow_conversations",
|
|
39
|
+
timestamps: true,
|
|
40
|
+
});
|
|
41
|
+
return YpWorkflowConversation;
|
|
42
|
+
}
|
|
43
|
+
static associate(models) {
|
|
44
|
+
YpWorkflowConversation.belongsTo(models.YpAgentProduct, {
|
|
45
|
+
foreignKey: "agentProductId",
|
|
46
|
+
as: "agentProduct",
|
|
47
|
+
});
|
|
48
|
+
YpWorkflowConversation.hasMany(models.YpAgentProductRun, {
|
|
49
|
+
foreignKey: "workflowId",
|
|
50
|
+
as: "agentProductRuns",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Model, DataTypes } from "sequelize";
|
|
2
|
+
import { sequelize } from "@policysynth/agents/dbModels/sequelize.js";
|
|
3
|
+
export class YpWorkflowConversation extends Model {
|
|
4
|
+
static initModel(sequelizeInstance = sequelize) {
|
|
5
|
+
YpWorkflowConversation.init({
|
|
6
|
+
id: {
|
|
7
|
+
type: DataTypes.INTEGER,
|
|
8
|
+
primaryKey: true,
|
|
9
|
+
autoIncrement: true,
|
|
10
|
+
},
|
|
11
|
+
agentProductId: {
|
|
12
|
+
type: DataTypes.INTEGER,
|
|
13
|
+
allowNull: true,
|
|
14
|
+
field: "agent_product_id",
|
|
15
|
+
},
|
|
16
|
+
userId: {
|
|
17
|
+
type: DataTypes.INTEGER,
|
|
18
|
+
allowNull: false,
|
|
19
|
+
field: "user_id",
|
|
20
|
+
},
|
|
21
|
+
configuration: {
|
|
22
|
+
type: DataTypes.JSONB,
|
|
23
|
+
allowNull: false,
|
|
24
|
+
defaultValue: {},
|
|
25
|
+
},
|
|
26
|
+
created_at: {
|
|
27
|
+
type: DataTypes.DATE,
|
|
28
|
+
allowNull: false,
|
|
29
|
+
defaultValue: DataTypes.NOW,
|
|
30
|
+
},
|
|
31
|
+
updated_at: {
|
|
32
|
+
type: DataTypes.DATE,
|
|
33
|
+
allowNull: false,
|
|
34
|
+
defaultValue: DataTypes.NOW,
|
|
35
|
+
},
|
|
36
|
+
}, {
|
|
37
|
+
sequelize: sequelizeInstance,
|
|
38
|
+
tableName: "workflow_conversations",
|
|
39
|
+
timestamps: false,
|
|
40
|
+
});
|
|
41
|
+
return YpWorkflowConversation;
|
|
42
|
+
}
|
|
43
|
+
static associate(models) {
|
|
44
|
+
YpWorkflowConversation.belongsTo(models.YpAgentProduct, {
|
|
45
|
+
foreignKey: "agentProductId",
|
|
46
|
+
as: "agentProduct",
|
|
47
|
+
});
|
|
48
|
+
YpWorkflowConversation.hasMany(models.YpAgentProductRun, {
|
|
49
|
+
foreignKey: "workflowId",
|
|
50
|
+
as: "agentProductRuns",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
package/controllers/users.cjs
CHANGED
|
@@ -1291,6 +1291,7 @@ router.get('/loggedInUser/isloggedin', function (req, res) {
|
|
|
1291
1291
|
user.dataValues.loginProvider = req.user.loginProvider;
|
|
1292
1292
|
if (req.user.isSamlEmployee)
|
|
1293
1293
|
user.dataValues.isSamlEmployee = req.user.isSamlEmployee;
|
|
1294
|
+
delete user.dataValues.private_profile_data;
|
|
1294
1295
|
setSAMLSettingsOnUser(req, user, (error) => {
|
|
1295
1296
|
if (error) {
|
|
1296
1297
|
log.error("User IsLoggedIn Error 2", { context: 'isloggedin', user: req.user.id, err: error, errorStatus: 500 });
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = {
|
|
3
|
+
up: async (queryInterface, Sequelize) => {
|
|
4
|
+
await queryInterface.createTable("workflow_conversations", {
|
|
5
|
+
id: {
|
|
6
|
+
type: Sequelize.INTEGER,
|
|
7
|
+
autoIncrement: true,
|
|
8
|
+
primaryKey: true,
|
|
9
|
+
allowNull: false,
|
|
10
|
+
},
|
|
11
|
+
agent_product_id: {
|
|
12
|
+
type: Sequelize.INTEGER,
|
|
13
|
+
allowNull: true,
|
|
14
|
+
references: {
|
|
15
|
+
model: "agent_products",
|
|
16
|
+
key: "id",
|
|
17
|
+
},
|
|
18
|
+
onDelete: "SET NULL",
|
|
19
|
+
},
|
|
20
|
+
user_id: {
|
|
21
|
+
type: Sequelize.INTEGER,
|
|
22
|
+
allowNull: false,
|
|
23
|
+
references: {
|
|
24
|
+
model: "users",
|
|
25
|
+
key: "id",
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
configuration: {
|
|
29
|
+
type: Sequelize.JSONB,
|
|
30
|
+
allowNull: false,
|
|
31
|
+
defaultValue: {},
|
|
32
|
+
},
|
|
33
|
+
created_at: {
|
|
34
|
+
type: Sequelize.DATE,
|
|
35
|
+
allowNull: false,
|
|
36
|
+
defaultValue: Sequelize.literal("NOW()"),
|
|
37
|
+
},
|
|
38
|
+
updated_at: {
|
|
39
|
+
type: Sequelize.DATE,
|
|
40
|
+
allowNull: false,
|
|
41
|
+
defaultValue: Sequelize.literal("NOW()"),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
// Optionally, add indexes for performance:
|
|
45
|
+
await queryInterface.addIndex("workflow_conversations", ["agent_product_id"]);
|
|
46
|
+
await queryInterface.addIndex("workflow_conversations", ["user_id"]);
|
|
47
|
+
await queryInterface.addColumn("agent_products", "parent_agent_product_id", {
|
|
48
|
+
type: Sequelize.INTEGER,
|
|
49
|
+
allowNull: true,
|
|
50
|
+
references: {
|
|
51
|
+
model: "agent_products",
|
|
52
|
+
key: "id",
|
|
53
|
+
},
|
|
54
|
+
onDelete: "SET NULL",
|
|
55
|
+
});
|
|
56
|
+
await queryInterface.addIndex("agent_products", ["parent_agent_product_id"]);
|
|
57
|
+
await queryInterface.addColumn("agent_product_runs", "workflowId", {
|
|
58
|
+
type: Sequelize.INTEGER,
|
|
59
|
+
allowNull: true,
|
|
60
|
+
references: {
|
|
61
|
+
model: "workflow_conversations",
|
|
62
|
+
key: "id",
|
|
63
|
+
},
|
|
64
|
+
onDelete: "SET NULL",
|
|
65
|
+
});
|
|
66
|
+
await queryInterface.addIndex("agent_product_runs", ["workflowId"]);
|
|
67
|
+
await queryInterface.addColumn("agent_product_runs", "parent_agent_product_run_id", {
|
|
68
|
+
type: Sequelize.INTEGER,
|
|
69
|
+
allowNull: true,
|
|
70
|
+
references: {
|
|
71
|
+
model: "agent_product_runs",
|
|
72
|
+
key: "id",
|
|
73
|
+
},
|
|
74
|
+
onDelete: "SET NULL",
|
|
75
|
+
});
|
|
76
|
+
await queryInterface.addIndex("agent_product_runs", ["parent_agent_product_run_id"]);
|
|
77
|
+
},
|
|
78
|
+
down: async (queryInterface, Sequelize) => {
|
|
79
|
+
await queryInterface.dropTable("workflow_conversations");
|
|
80
|
+
},
|
|
81
|
+
};
|